mirror of
https://github.com/LmeSzinc/StarRailCopilot.git
synced 2024-11-24 09:33:34 +00:00
Dev: Extract map worlds and planes, add extract framework
This commit is contained in:
parent
94b7bc4566
commit
1e79353294
@ -3,26 +3,15 @@ import os
|
|||||||
import re
|
import re
|
||||||
import typing as t
|
import typing as t
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from functools import cache, cached_property
|
from functools import cache
|
||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
|
|
||||||
|
from dev_tools.keywords.base import TextMap, UI_LANGUAGES, replace_templates, text_to_variable
|
||||||
from module.base.code_generator import CodeGenerator
|
from module.base.code_generator import CodeGenerator
|
||||||
from module.config.utils import deep_get, read_file
|
from module.config.utils import deep_get, read_file
|
||||||
from module.exception import ScriptError
|
from module.exception import ScriptError
|
||||||
from module.logger import logger
|
from module.logger import logger
|
||||||
|
|
||||||
UI_LANGUAGES = ['cn', 'cht', 'en', 'jp', 'es']
|
|
||||||
|
|
||||||
|
|
||||||
def text_to_variable(text):
|
|
||||||
text = re.sub("'s |s' ", '_', text)
|
|
||||||
text = re.sub('[ \-—:\'/•.]+', '_', text)
|
|
||||||
text = re.sub(r'[(),#"?!&%*]|</?\w+>', '', text)
|
|
||||||
# text = re.sub(r'[#_]?\d+(_times?)?', '', text)
|
|
||||||
text = re.sub(r'<color=#?\w+>', '', text)
|
|
||||||
text = text.replace('é', 'e')
|
|
||||||
return text.strip('_')
|
|
||||||
|
|
||||||
|
|
||||||
def dungeon_name(name: str) -> str:
|
def dungeon_name(name: str) -> str:
|
||||||
name = text_to_variable(name)
|
name = text_to_variable(name)
|
||||||
@ -61,72 +50,6 @@ def convert_inner_character_to_keyword(name):
|
|||||||
return convert_dict.get(name, name)
|
return convert_dict.get(name, name)
|
||||||
|
|
||||||
|
|
||||||
class TextMap:
|
|
||||||
DATA_FOLDER = ''
|
|
||||||
|
|
||||||
def __init__(self, lang: str):
|
|
||||||
self.lang = lang
|
|
||||||
|
|
||||||
def __contains__(self, name: t.Union[int, str]) -> bool:
|
|
||||||
if isinstance(name, int) or (isinstance(name, str) and name.isdigit()):
|
|
||||||
return int(name) in self.data
|
|
||||||
return False
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def data(self) -> dict[int, str]:
|
|
||||||
if not os.path.exists(TextMap.DATA_FOLDER):
|
|
||||||
logger.critical('`TextMap.DATA_FOLDER` does not exist, please set it to your path to StarRailData')
|
|
||||||
exit(1)
|
|
||||||
file = os.path.join(TextMap.DATA_FOLDER, 'TextMap', f'TextMap{self.lang.upper()}.json')
|
|
||||||
data = {}
|
|
||||||
for id_, text in read_file(file).items():
|
|
||||||
text = text.replace('\u00A0', '')
|
|
||||||
text = text.replace(r'{NICKNAME}', 'Trailblazer')
|
|
||||||
data[int(id_)] = text
|
|
||||||
return data
|
|
||||||
|
|
||||||
def find(self, name: t.Union[int, str]) -> tuple[int, str]:
|
|
||||||
"""
|
|
||||||
Args:
|
|
||||||
name:
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
text id (hash in TextMap)
|
|
||||||
text
|
|
||||||
"""
|
|
||||||
if isinstance(name, int) or (isinstance(name, str) and name.isdigit()):
|
|
||||||
name = int(name)
|
|
||||||
try:
|
|
||||||
return name, self.data[name]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
name = str(name)
|
|
||||||
for row_id, row_name in self.data.items():
|
|
||||||
if row_id >= 0 and row_name == name:
|
|
||||||
return row_id, row_name
|
|
||||||
for row_id, row_name in self.data.items():
|
|
||||||
if row_name == name:
|
|
||||||
return row_id, row_name
|
|
||||||
logger.error(f'Cannot find name: "{name}" in language {self.lang}')
|
|
||||||
return 0, ''
|
|
||||||
|
|
||||||
|
|
||||||
def replace_templates(text: str) -> str:
|
|
||||||
"""
|
|
||||||
Replace templates in data to make sure it equals to what is shown in game
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
replace_templates("Complete Echo of War #4 time(s)")
|
|
||||||
== "Complete Echo of War 1 time(s)"
|
|
||||||
"""
|
|
||||||
text = re.sub(r'#4', '1', text)
|
|
||||||
text = re.sub(r'</?\w+>', '', text)
|
|
||||||
text = re.sub(r'<color=#?\w+>', '', text)
|
|
||||||
text = re.sub(r'{.*?}', '', text)
|
|
||||||
return text
|
|
||||||
|
|
||||||
|
|
||||||
class KeywordExtract:
|
class KeywordExtract:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.text_map: dict[str, TextMap] = {lang: TextMap(lang) for lang in UI_LANGUAGES}
|
self.text_map: dict[str, TextMap] = {lang: TextMap(lang) for lang in UI_LANGUAGES}
|
||||||
@ -438,32 +361,10 @@ class KeywordExtract:
|
|||||||
self.write_keywords(keyword_class=class_name, output_file=output_file)
|
self.write_keywords(keyword_class=class_name, output_file=output_file)
|
||||||
|
|
||||||
def generate_map_planes(self):
|
def generate_map_planes(self):
|
||||||
planes = {
|
from dev_tools.keywords.map_world import GenerateMapWorld
|
||||||
'Special': ['黑塔的办公室', '锋芒崭露'],
|
GenerateMapWorld()()
|
||||||
'Rogue': [ '区域-战斗', '区域-事件', '区域-遭遇', '区域-休整', '区域-精英', '区域-首领', '区域-交易'],
|
from dev_tools.keywords.map_plane import GenerateMapPlane
|
||||||
'Herta': ['观景车厢', '主控舱段', '基座舱段', '收容舱段', '支援舱段', '禁闭舱段'],
|
GenerateMapPlane()()
|
||||||
'Jarilo': ['行政区', '城郊雪原', '边缘通路', '铁卫禁区', '残响回廊', '永冬岭',
|
|
||||||
'造物之柱', '旧武器试验场', '磐岩镇', '大矿区', '铆钉镇', '机械聚落'],
|
|
||||||
'Luofu': ['星槎海中枢', '流云渡', '迴星港', '长乐天', '金人巷', '太卜司',
|
|
||||||
'工造司', '绥园', '丹鼎司', '鳞渊境'],
|
|
||||||
}
|
|
||||||
|
|
||||||
def text_convert(world_):
|
|
||||||
def text_convert_wrapper(name):
|
|
||||||
name = text_to_variable(name).replace('_', '')
|
|
||||||
name = f'{world_}_{name}'
|
|
||||||
return name
|
|
||||||
|
|
||||||
return text_convert_wrapper
|
|
||||||
|
|
||||||
gen = None
|
|
||||||
for world, plane in planes.items():
|
|
||||||
self.load_keywords(plane)
|
|
||||||
gen = self.write_keywords(keyword_class='MapPlane', output_file='',
|
|
||||||
text_convert=text_convert(world), generator=gen)
|
|
||||||
gen.write('./tasks/map/keywords/plane.py')
|
|
||||||
self.load_keywords(['Herta Space Station', 'Jarilo-VI', 'The Xianzhou Luofu'], lang='en')
|
|
||||||
self.write_keywords(keyword_class='MapWorld', output_file='./tasks/map/keywords/world.py')
|
|
||||||
|
|
||||||
def generate_character_keywords(self):
|
def generate_character_keywords(self):
|
||||||
self.load_character_name_keywords()
|
self.load_character_name_keywords()
|
||||||
|
184
dev_tools/keywords/base.py
Normal file
184
dev_tools/keywords/base.py
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
import typing as t
|
||||||
|
from functools import cached_property
|
||||||
|
|
||||||
|
from module.base.code_generator import CodeGenerator
|
||||||
|
from module.config.utils import read_file
|
||||||
|
from module.logger import logger
|
||||||
|
|
||||||
|
UI_LANGUAGES = ['cn', 'cht', 'en', 'jp', 'es']
|
||||||
|
|
||||||
|
|
||||||
|
class TextMap:
|
||||||
|
DATA_FOLDER = ''
|
||||||
|
|
||||||
|
def __init__(self, lang: str):
|
||||||
|
self.lang = lang
|
||||||
|
|
||||||
|
def __contains__(self, name: t.Union[int, str]) -> bool:
|
||||||
|
if isinstance(name, int) or (isinstance(name, str) and name.isdigit()):
|
||||||
|
return int(name) in self.data
|
||||||
|
return False
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def data(self) -> dict[int, str]:
|
||||||
|
if not os.path.exists(TextMap.DATA_FOLDER):
|
||||||
|
logger.critical('`TextMap.DATA_FOLDER` does not exist, please set it to your path to StarRailData')
|
||||||
|
exit(1)
|
||||||
|
file = os.path.join(TextMap.DATA_FOLDER, 'TextMap', f'TextMap{self.lang.upper()}.json')
|
||||||
|
data = {}
|
||||||
|
for id_, text in read_file(file).items():
|
||||||
|
text = text.replace('\u00A0', '')
|
||||||
|
text = text.replace(r'{NICKNAME}', 'Trailblazer')
|
||||||
|
data[int(id_)] = text
|
||||||
|
return data
|
||||||
|
|
||||||
|
def find(self, name: t.Union[int, str]) -> tuple[int, str]:
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
name:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
text id (hash in TextMap)
|
||||||
|
text
|
||||||
|
"""
|
||||||
|
if isinstance(name, int) or (isinstance(name, str) and name.isdigit()):
|
||||||
|
name = int(name)
|
||||||
|
try:
|
||||||
|
return name, self.data[name]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
name = str(name)
|
||||||
|
for row_id, row_name in self.data.items():
|
||||||
|
if row_id >= 0 and row_name == name:
|
||||||
|
return row_id, row_name
|
||||||
|
for row_id, row_name in self.data.items():
|
||||||
|
if row_name == name:
|
||||||
|
return row_id, row_name
|
||||||
|
logger.error(f'Cannot find name: "{name}" in language {self.lang}')
|
||||||
|
return 0, ''
|
||||||
|
|
||||||
|
|
||||||
|
def text_to_variable(text):
|
||||||
|
text = re.sub("'s |s' ", '_', text)
|
||||||
|
text = re.sub(r'[ \-—:\'/•.]+', '_', text)
|
||||||
|
text = re.sub(r'[(),#"?!&%*]|</?\w+>', '', text)
|
||||||
|
# text = re.sub(r'[#_]?\d+(_times?)?', '', text)
|
||||||
|
text = re.sub(r'<color=#?\w+>', '', text)
|
||||||
|
text = text.replace('é', 'e')
|
||||||
|
return text.strip('_')
|
||||||
|
|
||||||
|
|
||||||
|
def replace_templates(text: str) -> str:
|
||||||
|
"""
|
||||||
|
Replace templates in data to make sure it equals to what is shown in game
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
replace_templates("Complete Echo of War #4 time(s)")
|
||||||
|
== "Complete Echo of War 1 time(s)"
|
||||||
|
"""
|
||||||
|
text = re.sub(r'#4', '1', text)
|
||||||
|
text = re.sub(r'</?\w+>', '', text)
|
||||||
|
text = re.sub(r'<color=#?\w+>', '', text)
|
||||||
|
text = re.sub(r'{.*?}', '', text)
|
||||||
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateKeyword:
|
||||||
|
text_map: dict[str, TextMap] = {lang: TextMap(lang) for lang in UI_LANGUAGES}
|
||||||
|
text_map['cn'] = TextMap('chs')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def read_file(file: str) -> dict:
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
file: ./ExcelOutput/GameplayGuideData.json
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
dict:
|
||||||
|
"""
|
||||||
|
file = os.path.join(TextMap.DATA_FOLDER, file)
|
||||||
|
return read_file(file)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_keyword(cls, keyword, lang) -> tuple[int, str]:
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
keyword: text string or text id
|
||||||
|
lang: Language to find
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
text id (hash in TextMap)
|
||||||
|
text
|
||||||
|
"""
|
||||||
|
text_map = cls.text_map[lang]
|
||||||
|
return text_map.find(keyword)
|
||||||
|
|
||||||
|
output_file = ''
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.gen = CodeGenerator()
|
||||||
|
self.keyword_class = self.__class__.__name__.removeprefix('Generate')
|
||||||
|
self.keyword_index = 0
|
||||||
|
self.keyword_format = {
|
||||||
|
'id': 0,
|
||||||
|
'name': 'Unnamed_Keyword'
|
||||||
|
}
|
||||||
|
for lang in UI_LANGUAGES:
|
||||||
|
self.keyword_format[lang] = ''
|
||||||
|
|
||||||
|
def gen_import(self):
|
||||||
|
self.gen.Import(
|
||||||
|
f"""
|
||||||
|
from .classes import {self.keyword_class}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
def iter_keywords(self) -> t.Iterable[dict]:
|
||||||
|
"""
|
||||||
|
Yields
|
||||||
|
dict: {'text_id': 123456, 'any_attr': 1}
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def convert_name(self, text: str, keyword: dict) -> str:
|
||||||
|
return text_to_variable(text)
|
||||||
|
|
||||||
|
def format_keywords(self, keyword: dict) -> dict | None:
|
||||||
|
base = self.keyword_format.copy()
|
||||||
|
text_id = keyword.pop('text_id')
|
||||||
|
if text_id is None:
|
||||||
|
return
|
||||||
|
# id
|
||||||
|
self.keyword_index += 1
|
||||||
|
base['id'] = self.keyword_index
|
||||||
|
# Attrs
|
||||||
|
base.update(keyword)
|
||||||
|
# Name
|
||||||
|
_, name = self.find_keyword(text_id, lang='en')
|
||||||
|
name = self.convert_name(replace_templates(name), keyword=base)
|
||||||
|
base['name'] = name
|
||||||
|
# Translations
|
||||||
|
for lang in UI_LANGUAGES:
|
||||||
|
value = replace_templates(self.find_keyword(text_id, lang=lang)[1])
|
||||||
|
base[lang] = value
|
||||||
|
return base
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
self.gen_import()
|
||||||
|
self.gen.CommentAutoGenerage('dev_tools.keyword_extract')
|
||||||
|
|
||||||
|
for keyword in self.iter_keywords():
|
||||||
|
keyword = self.format_keywords(keyword)
|
||||||
|
with self.gen.Object(key=keyword['name'], object_class=self.keyword_class):
|
||||||
|
for key, value in keyword.items():
|
||||||
|
self.gen.ObjectAttr(key, value)
|
||||||
|
|
||||||
|
if self.output_file:
|
||||||
|
print(f'Write {self.output_file}')
|
||||||
|
self.gen.write(self.output_file)
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
self.generate()
|
70
dev_tools/keywords/map_plane.py
Normal file
70
dev_tools/keywords/map_plane.py
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import typing as t
|
||||||
|
|
||||||
|
from dev_tools.keywords.base import GenerateKeyword
|
||||||
|
from module.base.decorator import cached_property
|
||||||
|
from module.config.utils import deep_get
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateMapPlane(GenerateKeyword):
|
||||||
|
output_file = './tasks/map/keywords/plane.py'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def data(self):
|
||||||
|
return self.read_file('./ExcelOutput/AreaMapConfig.json')
|
||||||
|
|
||||||
|
def iter_planes(self) -> t.Iterable[dict]:
|
||||||
|
for plane_id, data in self.data.items():
|
||||||
|
plane_id = int(plane_id)
|
||||||
|
world_id = int(str(plane_id)[-5])
|
||||||
|
sort_id = int(deep_get(data, 'MenuSortID', 0))
|
||||||
|
text_id = deep_get(data, 'Name.Hash')
|
||||||
|
yield dict(
|
||||||
|
text_id=text_id,
|
||||||
|
world_id=world_id,
|
||||||
|
plane_id=plane_id,
|
||||||
|
sort_id=sort_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
def iter_keywords(self) -> t.Iterable[dict]:
|
||||||
|
"""
|
||||||
|
1010201
|
||||||
|
^^ floor
|
||||||
|
^^ plane
|
||||||
|
^ world
|
||||||
|
"""
|
||||||
|
def to_id(name):
|
||||||
|
return self.find_keyword(name, lang='cn')[0]
|
||||||
|
|
||||||
|
domains = ['黑塔的办公室', '锋芒崭露']
|
||||||
|
for index, domain in enumerate(domains):
|
||||||
|
yield dict(
|
||||||
|
text_id=to_id(domain),
|
||||||
|
world_id=-1,
|
||||||
|
plane_id=index + 1,
|
||||||
|
)
|
||||||
|
domains = ['区域-战斗', '区域-事件', '区域-遭遇', '区域-休整', '区域-精英', '区域-首领', '区域-交易']
|
||||||
|
for index, domain in enumerate(domains):
|
||||||
|
yield dict(
|
||||||
|
text_id=to_id(domain),
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=index + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
keywords = sorted(self.iter_planes(), key=lambda x: (x['world_id'], x['sort_id']))
|
||||||
|
for keyword in keywords:
|
||||||
|
keyword.pop('sort_id')
|
||||||
|
yield keyword
|
||||||
|
|
||||||
|
def convert_name(self, text: str, keyword: dict) -> str:
|
||||||
|
text = super().convert_name(text, keyword=keyword)
|
||||||
|
text = text.replace('_', '')
|
||||||
|
|
||||||
|
from tasks.map.keywords import MapWorld
|
||||||
|
world = MapWorld.find_world_id(keyword['world_id'])
|
||||||
|
if world is None:
|
||||||
|
if text.startswith('Domain'):
|
||||||
|
return f'Rogue_{text}'
|
||||||
|
else:
|
||||||
|
return f'Special_{text}'
|
||||||
|
else:
|
||||||
|
return f'{world.short_name}_{text}'
|
33
dev_tools/keywords/map_world.py
Normal file
33
dev_tools/keywords/map_world.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import typing as t
|
||||||
|
|
||||||
|
from dev_tools.keywords.base import GenerateKeyword
|
||||||
|
|
||||||
|
|
||||||
|
class GenerateMapWorld(GenerateKeyword):
|
||||||
|
output_file = './tasks/map/keywords/world.py'
|
||||||
|
|
||||||
|
def iter_keywords(self) -> t.Iterable[dict]:
|
||||||
|
|
||||||
|
def to_id(name):
|
||||||
|
return self.find_keyword(name, lang='en')[0]
|
||||||
|
|
||||||
|
yield dict(
|
||||||
|
text_id=to_id('Herta Space Station'),
|
||||||
|
world_id=0,
|
||||||
|
short_name='Herta'
|
||||||
|
)
|
||||||
|
yield dict(
|
||||||
|
text_id=to_id('Jarilo-VI'),
|
||||||
|
world_id=1,
|
||||||
|
short_name='Jarilo'
|
||||||
|
)
|
||||||
|
yield dict(
|
||||||
|
text_id=to_id('The Xianzhou Luofu'),
|
||||||
|
world_id=2,
|
||||||
|
short_name='Luofu'
|
||||||
|
)
|
||||||
|
yield dict(
|
||||||
|
text_id=to_id('Penacony'),
|
||||||
|
world_id=3,
|
||||||
|
short_name='Penacony'
|
||||||
|
)
|
@ -17,11 +17,11 @@ FLOOR_BUTTONS = [FLOOR_1, FLOOR_2, FLOOR_3]
|
|||||||
|
|
||||||
|
|
||||||
def world_entrance(plane: MapPlane) -> ButtonWrapper:
|
def world_entrance(plane: MapPlane) -> ButtonWrapper:
|
||||||
if plane.is_HertaSpaceStation:
|
if plane.world.is_Herta:
|
||||||
return WORLD_HERTA
|
return WORLD_HERTA
|
||||||
if plane.is_JariloVI:
|
if plane.world.is_Jarilo:
|
||||||
return WORLD_JARILO
|
return WORLD_JARILO
|
||||||
if plane.is_Luofu:
|
if plane.world.is_Luofu:
|
||||||
return WORLD_LUOFU
|
return WORLD_LUOFU
|
||||||
raise ScriptError(f'world_entrance() got unknown plane: {plane}')
|
raise ScriptError(f'world_entrance() got unknown plane: {plane}')
|
||||||
|
|
||||||
|
@ -10,6 +10,11 @@ from module.ocr.keyword import Keyword
|
|||||||
class MapPlane(Keyword):
|
class MapPlane(Keyword):
|
||||||
instances: ClassVar = {}
|
instances: ClassVar = {}
|
||||||
|
|
||||||
|
# 0, 1, 2, 3
|
||||||
|
world_id: int
|
||||||
|
# 1010201
|
||||||
|
plane_id: int
|
||||||
|
|
||||||
# Map floors, 'F1' by default
|
# Map floors, 'F1' by default
|
||||||
# Example: ['B1', 'F1', 'F2']
|
# Example: ['B1', 'F1', 'F2']
|
||||||
floors = ['F1']
|
floors = ['F1']
|
||||||
@ -18,33 +23,27 @@ class MapPlane(Keyword):
|
|||||||
# 'top' or 'bottom'
|
# 'top' or 'bottom'
|
||||||
page = 'top'
|
page = 'top'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_plane_id(cls, plane_id):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
plane_id:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
MapPlane: MapPlane object or None
|
||||||
|
"""
|
||||||
|
for instance in cls.instances.values():
|
||||||
|
if instance.plane_id == plane_id:
|
||||||
|
return instance
|
||||||
|
return None
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def world(self) -> str:
|
def world(self) -> "MapWorld":
|
||||||
"""
|
"""
|
||||||
Returns:
|
Returns:
|
||||||
str: World name. Note that "Parlor Car" is considered as a plane of Herta.
|
MapWorld: MapWorld object or None
|
||||||
"Herta" for Herta Space Station
|
|
||||||
"Jarilo" for Jarilo-VI
|
|
||||||
"Luofu" for The Xianzhou Luofu
|
|
||||||
"" for unknown
|
|
||||||
"""
|
"""
|
||||||
for world in ['Herta', 'Jarilo', 'Luofu']:
|
return MapWorld.find_world_id(self.world_id)
|
||||||
if self.name.startswith(world):
|
|
||||||
return world
|
|
||||||
|
|
||||||
return ''
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def is_HertaSpaceStation(self):
|
|
||||||
return self.world == 'Herta'
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def is_JariloVI(self):
|
|
||||||
return self.world == 'Jarilo'
|
|
||||||
|
|
||||||
@cached_property
|
|
||||||
def is_Luofu(self):
|
|
||||||
return self.world == 'Luofu'
|
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def has_multiple_floors(self):
|
def has_multiple_floors(self):
|
||||||
@ -135,3 +134,38 @@ class MapPlane(Keyword):
|
|||||||
@dataclass(repr=False)
|
@dataclass(repr=False)
|
||||||
class MapWorld(Keyword):
|
class MapWorld(Keyword):
|
||||||
instances: ClassVar = {}
|
instances: ClassVar = {}
|
||||||
|
|
||||||
|
# 0, 1, 2, 3
|
||||||
|
world_id: int
|
||||||
|
# Herta
|
||||||
|
short_name: str
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_world_id(cls, world_id):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
world_id:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
MapWorld: MapWorld object or None
|
||||||
|
"""
|
||||||
|
for instance in cls.instances.values():
|
||||||
|
if instance.world_id == world_id:
|
||||||
|
return instance
|
||||||
|
return None
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def is_Herta(self):
|
||||||
|
return self.short_name == 'Herta'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def is_Jarilo(self):
|
||||||
|
return self.short_name == 'Jarilo'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def is_Luofu(self):
|
||||||
|
return self.short_name == 'Luofu'
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def is_Penacony(self):
|
||||||
|
return self.short_name == 'Penacony'
|
||||||
|
@ -11,6 +11,8 @@ Special_HertaOffice = MapPlane(
|
|||||||
en="Herta's Office",
|
en="Herta's Office",
|
||||||
jp='ヘルタのオフィス',
|
jp='ヘルタのオフィス',
|
||||||
es='Oficina de Herta',
|
es='Oficina de Herta',
|
||||||
|
world_id=-1,
|
||||||
|
plane_id=1,
|
||||||
)
|
)
|
||||||
Special_AptitudeShowcase = MapPlane(
|
Special_AptitudeShowcase = MapPlane(
|
||||||
id=2,
|
id=2,
|
||||||
@ -20,6 +22,8 @@ Special_AptitudeShowcase = MapPlane(
|
|||||||
en='Aptitude Showcase',
|
en='Aptitude Showcase',
|
||||||
jp='躍進する新星',
|
jp='躍進する新星',
|
||||||
es='Demostración de aptitudes',
|
es='Demostración de aptitudes',
|
||||||
|
world_id=-1,
|
||||||
|
plane_id=2,
|
||||||
)
|
)
|
||||||
Rogue_DomainCombat = MapPlane(
|
Rogue_DomainCombat = MapPlane(
|
||||||
id=3,
|
id=3,
|
||||||
@ -29,6 +33,8 @@ Rogue_DomainCombat = MapPlane(
|
|||||||
en='Domain — Combat',
|
en='Domain — Combat',
|
||||||
jp='エリア-戦闘',
|
jp='エリア-戦闘',
|
||||||
es='Batalla',
|
es='Batalla',
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=1,
|
||||||
)
|
)
|
||||||
Rogue_DomainOccurrence = MapPlane(
|
Rogue_DomainOccurrence = MapPlane(
|
||||||
id=4,
|
id=4,
|
||||||
@ -38,6 +44,8 @@ Rogue_DomainOccurrence = MapPlane(
|
|||||||
en='Domain — Occurrence',
|
en='Domain — Occurrence',
|
||||||
jp='エリア-イベント',
|
jp='エリア-イベント',
|
||||||
es='Evento',
|
es='Evento',
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=2,
|
||||||
)
|
)
|
||||||
Rogue_DomainEncounter = MapPlane(
|
Rogue_DomainEncounter = MapPlane(
|
||||||
id=5,
|
id=5,
|
||||||
@ -47,6 +55,8 @@ Rogue_DomainEncounter = MapPlane(
|
|||||||
en='Domain — Encounter',
|
en='Domain — Encounter',
|
||||||
jp='エリア-遭遇',
|
jp='エリア-遭遇',
|
||||||
es='Encuentro',
|
es='Encuentro',
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=3,
|
||||||
)
|
)
|
||||||
Rogue_DomainRespite = MapPlane(
|
Rogue_DomainRespite = MapPlane(
|
||||||
id=6,
|
id=6,
|
||||||
@ -56,6 +66,8 @@ Rogue_DomainRespite = MapPlane(
|
|||||||
en='Domain — Respite',
|
en='Domain — Respite',
|
||||||
jp='エリア-休憩',
|
jp='エリア-休憩',
|
||||||
es='Reposo',
|
es='Reposo',
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=4,
|
||||||
)
|
)
|
||||||
Rogue_DomainElite = MapPlane(
|
Rogue_DomainElite = MapPlane(
|
||||||
id=7,
|
id=7,
|
||||||
@ -65,6 +77,8 @@ Rogue_DomainElite = MapPlane(
|
|||||||
en='Domain — Elite',
|
en='Domain — Elite',
|
||||||
jp='エリア-精鋭',
|
jp='エリア-精鋭',
|
||||||
es='Élite',
|
es='Élite',
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=5,
|
||||||
)
|
)
|
||||||
Rogue_DomainBoss = MapPlane(
|
Rogue_DomainBoss = MapPlane(
|
||||||
id=8,
|
id=8,
|
||||||
@ -74,6 +88,8 @@ Rogue_DomainBoss = MapPlane(
|
|||||||
en='Domain — Boss',
|
en='Domain — Boss',
|
||||||
jp='エリア-ボス',
|
jp='エリア-ボス',
|
||||||
es='Jefe',
|
es='Jefe',
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=6,
|
||||||
)
|
)
|
||||||
Rogue_DomainTransaction = MapPlane(
|
Rogue_DomainTransaction = MapPlane(
|
||||||
id=9,
|
id=9,
|
||||||
@ -83,6 +99,8 @@ Rogue_DomainTransaction = MapPlane(
|
|||||||
en='Domain — Transaction',
|
en='Domain — Transaction',
|
||||||
jp='エリア-取引',
|
jp='エリア-取引',
|
||||||
es='Transacción',
|
es='Transacción',
|
||||||
|
world_id=-2,
|
||||||
|
plane_id=7,
|
||||||
)
|
)
|
||||||
Herta_ParlorCar = MapPlane(
|
Herta_ParlorCar = MapPlane(
|
||||||
id=10,
|
id=10,
|
||||||
@ -92,6 +110,8 @@ Herta_ParlorCar = MapPlane(
|
|||||||
en='Parlor Car',
|
en='Parlor Car',
|
||||||
jp='列車のラウンジ',
|
jp='列車のラウンジ',
|
||||||
es='Vagón panorámico',
|
es='Vagón panorámico',
|
||||||
|
world_id=0,
|
||||||
|
plane_id=1000001,
|
||||||
)
|
)
|
||||||
Herta_MasterControlZone = MapPlane(
|
Herta_MasterControlZone = MapPlane(
|
||||||
id=11,
|
id=11,
|
||||||
@ -101,6 +121,8 @@ Herta_MasterControlZone = MapPlane(
|
|||||||
en='Master Control Zone',
|
en='Master Control Zone',
|
||||||
jp='主制御部分',
|
jp='主制御部分',
|
||||||
es='Zona de mando principal',
|
es='Zona de mando principal',
|
||||||
|
world_id=0,
|
||||||
|
plane_id=1000101,
|
||||||
)
|
)
|
||||||
Herta_BaseZone = MapPlane(
|
Herta_BaseZone = MapPlane(
|
||||||
id=12,
|
id=12,
|
||||||
@ -110,6 +132,8 @@ Herta_BaseZone = MapPlane(
|
|||||||
en='Base Zone',
|
en='Base Zone',
|
||||||
jp='ベース部分',
|
jp='ベース部分',
|
||||||
es='Zona de la base',
|
es='Zona de la base',
|
||||||
|
world_id=0,
|
||||||
|
plane_id=2000101,
|
||||||
)
|
)
|
||||||
Herta_StorageZone = MapPlane(
|
Herta_StorageZone = MapPlane(
|
||||||
id=13,
|
id=13,
|
||||||
@ -119,6 +143,8 @@ Herta_StorageZone = MapPlane(
|
|||||||
en='Storage Zone',
|
en='Storage Zone',
|
||||||
jp='収容部分',
|
jp='収容部分',
|
||||||
es='Zona de almacenamiento',
|
es='Zona de almacenamiento',
|
||||||
|
world_id=0,
|
||||||
|
plane_id=2000201,
|
||||||
)
|
)
|
||||||
Herta_SupplyZone = MapPlane(
|
Herta_SupplyZone = MapPlane(
|
||||||
id=14,
|
id=14,
|
||||||
@ -128,6 +154,8 @@ Herta_SupplyZone = MapPlane(
|
|||||||
en='Supply Zone',
|
en='Supply Zone',
|
||||||
jp='サポート部分',
|
jp='サポート部分',
|
||||||
es='Zona de suministros',
|
es='Zona de suministros',
|
||||||
|
world_id=0,
|
||||||
|
plane_id=2000301,
|
||||||
)
|
)
|
||||||
Herta_SeclusionZone = MapPlane(
|
Herta_SeclusionZone = MapPlane(
|
||||||
id=15,
|
id=15,
|
||||||
@ -137,6 +165,8 @@ Herta_SeclusionZone = MapPlane(
|
|||||||
en='Seclusion Zone',
|
en='Seclusion Zone',
|
||||||
jp='封鎖部分',
|
jp='封鎖部分',
|
||||||
es='Zona de confinamiento',
|
es='Zona de confinamiento',
|
||||||
|
world_id=0,
|
||||||
|
plane_id=2000401,
|
||||||
)
|
)
|
||||||
Jarilo_AdministrativeDistrict = MapPlane(
|
Jarilo_AdministrativeDistrict = MapPlane(
|
||||||
id=16,
|
id=16,
|
||||||
@ -146,6 +176,8 @@ Jarilo_AdministrativeDistrict = MapPlane(
|
|||||||
en='Administrative District',
|
en='Administrative District',
|
||||||
jp='行政区',
|
jp='行政区',
|
||||||
es='Distrito administrativo',
|
es='Distrito administrativo',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=1010101,
|
||||||
)
|
)
|
||||||
Jarilo_OutlyingSnowPlains = MapPlane(
|
Jarilo_OutlyingSnowPlains = MapPlane(
|
||||||
id=17,
|
id=17,
|
||||||
@ -155,6 +187,8 @@ Jarilo_OutlyingSnowPlains = MapPlane(
|
|||||||
en='Outlying Snow Plains',
|
en='Outlying Snow Plains',
|
||||||
jp='郊外雪原',
|
jp='郊外雪原',
|
||||||
es='Llanuras nevadas de las afueras',
|
es='Llanuras nevadas de las afueras',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2010101,
|
||||||
)
|
)
|
||||||
Jarilo_BackwaterPass = MapPlane(
|
Jarilo_BackwaterPass = MapPlane(
|
||||||
id=18,
|
id=18,
|
||||||
@ -164,6 +198,8 @@ Jarilo_BackwaterPass = MapPlane(
|
|||||||
en='Backwater Pass',
|
en='Backwater Pass',
|
||||||
jp='外縁通路',
|
jp='外縁通路',
|
||||||
es='Paso del Remanso',
|
es='Paso del Remanso',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2011101,
|
||||||
)
|
)
|
||||||
Jarilo_SilvermaneGuardRestrictedZone = MapPlane(
|
Jarilo_SilvermaneGuardRestrictedZone = MapPlane(
|
||||||
id=19,
|
id=19,
|
||||||
@ -173,6 +209,8 @@ Jarilo_SilvermaneGuardRestrictedZone = MapPlane(
|
|||||||
en='Silvermane Guard Restricted Zone',
|
en='Silvermane Guard Restricted Zone',
|
||||||
jp='シルバーメイン禁区',
|
jp='シルバーメイン禁区',
|
||||||
es='Zona restringida de la Guardia Crinargenta',
|
es='Zona restringida de la Guardia Crinargenta',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2013101,
|
||||||
)
|
)
|
||||||
Jarilo_CorridorofFadingEchoes = MapPlane(
|
Jarilo_CorridorofFadingEchoes = MapPlane(
|
||||||
id=20,
|
id=20,
|
||||||
@ -182,6 +220,8 @@ Jarilo_CorridorofFadingEchoes = MapPlane(
|
|||||||
en='Corridor of Fading Echoes',
|
en='Corridor of Fading Echoes',
|
||||||
jp='残響回廊',
|
jp='残響回廊',
|
||||||
es='Pasadizo de los ecos apagados',
|
es='Pasadizo de los ecos apagados',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2013201,
|
||||||
)
|
)
|
||||||
Jarilo_EverwinterHill = MapPlane(
|
Jarilo_EverwinterHill = MapPlane(
|
||||||
id=21,
|
id=21,
|
||||||
@ -191,6 +231,8 @@ Jarilo_EverwinterHill = MapPlane(
|
|||||||
en='Everwinter Hill',
|
en='Everwinter Hill',
|
||||||
jp='常冬峰',
|
jp='常冬峰',
|
||||||
es='Colina del Siempreinvierno',
|
es='Colina del Siempreinvierno',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2013401,
|
||||||
)
|
)
|
||||||
Jarilo_PillarsofCreation = MapPlane(
|
Jarilo_PillarsofCreation = MapPlane(
|
||||||
id=22,
|
id=22,
|
||||||
@ -200,6 +242,8 @@ Jarilo_PillarsofCreation = MapPlane(
|
|||||||
en='Pillars of Creation',
|
en='Pillars of Creation',
|
||||||
jp='造物の柱',
|
jp='造物の柱',
|
||||||
es='Pilares de la Creación',
|
es='Pilares de la Creación',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2013501,
|
||||||
)
|
)
|
||||||
Jarilo_OldWeaponTestingGround = MapPlane(
|
Jarilo_OldWeaponTestingGround = MapPlane(
|
||||||
id=23,
|
id=23,
|
||||||
@ -209,6 +253,8 @@ Jarilo_OldWeaponTestingGround = MapPlane(
|
|||||||
en='Old Weapon Testing Ground',
|
en='Old Weapon Testing Ground',
|
||||||
jp='旧武器実験場',
|
jp='旧武器実験場',
|
||||||
es='Antiguo campo de prueba de armas',
|
es='Antiguo campo de prueba de armas',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2013601,
|
||||||
)
|
)
|
||||||
Jarilo_BoulderTown = MapPlane(
|
Jarilo_BoulderTown = MapPlane(
|
||||||
id=24,
|
id=24,
|
||||||
@ -218,6 +264,8 @@ Jarilo_BoulderTown = MapPlane(
|
|||||||
en='Boulder Town',
|
en='Boulder Town',
|
||||||
jp='ボルダータウン',
|
jp='ボルダータウン',
|
||||||
es='Villarroca',
|
es='Villarroca',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=1010201,
|
||||||
)
|
)
|
||||||
Jarilo_GreatMine = MapPlane(
|
Jarilo_GreatMine = MapPlane(
|
||||||
id=25,
|
id=25,
|
||||||
@ -227,6 +275,8 @@ Jarilo_GreatMine = MapPlane(
|
|||||||
en='Great Mine',
|
en='Great Mine',
|
||||||
jp='大鉱区',
|
jp='大鉱区',
|
||||||
es='Mina principal',
|
es='Mina principal',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2012101,
|
||||||
)
|
)
|
||||||
Jarilo_RivetTown = MapPlane(
|
Jarilo_RivetTown = MapPlane(
|
||||||
id=26,
|
id=26,
|
||||||
@ -236,6 +286,8 @@ Jarilo_RivetTown = MapPlane(
|
|||||||
en='Rivet Town',
|
en='Rivet Town',
|
||||||
jp='リベットタウン',
|
jp='リベットタウン',
|
||||||
es='Villarremache',
|
es='Villarremache',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2012201,
|
||||||
)
|
)
|
||||||
Jarilo_RobotSettlement = MapPlane(
|
Jarilo_RobotSettlement = MapPlane(
|
||||||
id=27,
|
id=27,
|
||||||
@ -245,6 +297,8 @@ Jarilo_RobotSettlement = MapPlane(
|
|||||||
en='Robot Settlement',
|
en='Robot Settlement',
|
||||||
jp='機械集落',
|
jp='機械集落',
|
||||||
es='Asentamiento robot',
|
es='Asentamiento robot',
|
||||||
|
world_id=1,
|
||||||
|
plane_id=2012301,
|
||||||
)
|
)
|
||||||
Luofu_CentralStarskiffHaven = MapPlane(
|
Luofu_CentralStarskiffHaven = MapPlane(
|
||||||
id=28,
|
id=28,
|
||||||
@ -254,6 +308,8 @@ Luofu_CentralStarskiffHaven = MapPlane(
|
|||||||
en='Central Starskiff Haven',
|
en='Central Starskiff Haven',
|
||||||
jp='星槎海中枢',
|
jp='星槎海中枢',
|
||||||
es='Zona central de la Dársena de astroesquifes',
|
es='Zona central de la Dársena de astroesquifes',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=1020101,
|
||||||
)
|
)
|
||||||
Luofu_Cloudford = MapPlane(
|
Luofu_Cloudford = MapPlane(
|
||||||
id=29,
|
id=29,
|
||||||
@ -263,6 +319,8 @@ Luofu_Cloudford = MapPlane(
|
|||||||
en='Cloudford',
|
en='Cloudford',
|
||||||
jp='流雲渡し',
|
jp='流雲渡し',
|
||||||
es='Vado de las Nubes',
|
es='Vado de las Nubes',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=2021101,
|
||||||
)
|
)
|
||||||
Luofu_StargazerNavalia = MapPlane(
|
Luofu_StargazerNavalia = MapPlane(
|
||||||
id=30,
|
id=30,
|
||||||
@ -272,6 +330,8 @@ Luofu_StargazerNavalia = MapPlane(
|
|||||||
en='Stargazer Navalia',
|
en='Stargazer Navalia',
|
||||||
jp='廻星港',
|
jp='廻星港',
|
||||||
es='Puerto Miraestrellas',
|
es='Puerto Miraestrellas',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=2021201,
|
||||||
)
|
)
|
||||||
Luofu_ExaltingSanctum = MapPlane(
|
Luofu_ExaltingSanctum = MapPlane(
|
||||||
id=31,
|
id=31,
|
||||||
@ -281,6 +341,8 @@ Luofu_ExaltingSanctum = MapPlane(
|
|||||||
en='Exalting Sanctum',
|
en='Exalting Sanctum',
|
||||||
jp='長楽天',
|
jp='長楽天',
|
||||||
es='Sánctum de la Exaltación',
|
es='Sánctum de la Exaltación',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=1020201,
|
||||||
)
|
)
|
||||||
Luofu_AurumAlley = MapPlane(
|
Luofu_AurumAlley = MapPlane(
|
||||||
id=32,
|
id=32,
|
||||||
@ -290,6 +352,8 @@ Luofu_AurumAlley = MapPlane(
|
|||||||
en='Aurum Alley',
|
en='Aurum Alley',
|
||||||
jp='金人巷',
|
jp='金人巷',
|
||||||
es='Callejón Aurum',
|
es='Callejón Aurum',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=1020204,
|
||||||
)
|
)
|
||||||
Luofu_DivinationCommission = MapPlane(
|
Luofu_DivinationCommission = MapPlane(
|
||||||
id=33,
|
id=33,
|
||||||
@ -299,6 +363,8 @@ Luofu_DivinationCommission = MapPlane(
|
|||||||
en='Divination Commission',
|
en='Divination Commission',
|
||||||
jp='太卜司',
|
jp='太卜司',
|
||||||
es='Comisión de Adivinación',
|
es='Comisión de Adivinación',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=2022101,
|
||||||
)
|
)
|
||||||
Luofu_ArtisanshipCommission = MapPlane(
|
Luofu_ArtisanshipCommission = MapPlane(
|
||||||
id=34,
|
id=34,
|
||||||
@ -308,6 +374,8 @@ Luofu_ArtisanshipCommission = MapPlane(
|
|||||||
en='Artisanship Commission',
|
en='Artisanship Commission',
|
||||||
jp='工造司',
|
jp='工造司',
|
||||||
es='Comisión de Artesanía',
|
es='Comisión de Artesanía',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=2022201,
|
||||||
)
|
)
|
||||||
Luofu_FyxestrollGarden = MapPlane(
|
Luofu_FyxestrollGarden = MapPlane(
|
||||||
id=35,
|
id=35,
|
||||||
@ -317,6 +385,8 @@ Luofu_FyxestrollGarden = MapPlane(
|
|||||||
en='Fyxestroll Garden',
|
en='Fyxestroll Garden',
|
||||||
jp='綏園',
|
jp='綏園',
|
||||||
es='Jardín del Sosiego',
|
es='Jardín del Sosiego',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=2022301,
|
||||||
)
|
)
|
||||||
Luofu_AlchemyCommission = MapPlane(
|
Luofu_AlchemyCommission = MapPlane(
|
||||||
id=36,
|
id=36,
|
||||||
@ -326,6 +396,8 @@ Luofu_AlchemyCommission = MapPlane(
|
|||||||
en='Alchemy Commission',
|
en='Alchemy Commission',
|
||||||
jp='丹鼎司',
|
jp='丹鼎司',
|
||||||
es='Comisión de Alquimia',
|
es='Comisión de Alquimia',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=2023101,
|
||||||
)
|
)
|
||||||
Luofu_ScalegorgeWaterscape = MapPlane(
|
Luofu_ScalegorgeWaterscape = MapPlane(
|
||||||
id=37,
|
id=37,
|
||||||
@ -335,4 +407,61 @@ Luofu_ScalegorgeWaterscape = MapPlane(
|
|||||||
en='Scalegorge Waterscape',
|
en='Scalegorge Waterscape',
|
||||||
jp='鱗淵境',
|
jp='鱗淵境',
|
||||||
es='Desfiladero de Escamas',
|
es='Desfiladero de Escamas',
|
||||||
|
world_id=2,
|
||||||
|
plane_id=2023201,
|
||||||
|
)
|
||||||
|
Penacony_TheReverieReality = MapPlane(
|
||||||
|
id=38,
|
||||||
|
name='Penacony_TheReverieReality',
|
||||||
|
cn='「白日梦」酒店-现实',
|
||||||
|
cht='「白日夢」飯店-現實',
|
||||||
|
en='The Reverie (Reality)',
|
||||||
|
jp='ホテル・レバリー-現実',
|
||||||
|
es='Hotel Fantasía (realidad)',
|
||||||
|
world_id=3,
|
||||||
|
plane_id=1030501,
|
||||||
|
)
|
||||||
|
Penacony_GoldenHour = MapPlane(
|
||||||
|
id=39,
|
||||||
|
name='Penacony_GoldenHour',
|
||||||
|
cn='黄金的时刻',
|
||||||
|
cht='黃金的時刻',
|
||||||
|
en='Golden Hour',
|
||||||
|
jp='黄金の刻',
|
||||||
|
es='Momento Dorado',
|
||||||
|
world_id=3,
|
||||||
|
plane_id=1030101,
|
||||||
|
)
|
||||||
|
Penacony_DreamEdge = MapPlane(
|
||||||
|
id=40,
|
||||||
|
name='Penacony_DreamEdge',
|
||||||
|
cn='筑梦边境',
|
||||||
|
cht='築夢邊境',
|
||||||
|
en="Dream's Edge",
|
||||||
|
jp='ドリームボーダー',
|
||||||
|
es='Frontera de los Sueños',
|
||||||
|
world_id=3,
|
||||||
|
plane_id=2031301,
|
||||||
|
)
|
||||||
|
Penacony_AChildDream = MapPlane(
|
||||||
|
id=41,
|
||||||
|
name='Penacony_AChildDream',
|
||||||
|
cn='稚子的梦',
|
||||||
|
cht='稚子的夢',
|
||||||
|
en="A Child's Dream",
|
||||||
|
jp='稚児の夢',
|
||||||
|
es='Sueño infantil',
|
||||||
|
world_id=3,
|
||||||
|
plane_id=2031201,
|
||||||
|
)
|
||||||
|
Penacony_TheReverieDreamscape = MapPlane(
|
||||||
|
id=42,
|
||||||
|
name='Penacony_TheReverieDreamscape',
|
||||||
|
cn='「白日梦」酒店-梦境',
|
||||||
|
cht='「白日夢」飯店-夢境',
|
||||||
|
en='The Reverie (Dreamscape)',
|
||||||
|
jp='ホテル・レバリー-夢境',
|
||||||
|
es='Hotel Fantasía (paisaje onírico)',
|
||||||
|
world_id=3,
|
||||||
|
plane_id=2031101,
|
||||||
)
|
)
|
||||||
|
@ -11,6 +11,8 @@ Herta_Space_Station = MapWorld(
|
|||||||
en='Herta Space Station',
|
en='Herta Space Station',
|
||||||
jp='宇宙ステーション「ヘルタ」',
|
jp='宇宙ステーション「ヘルタ」',
|
||||||
es='Estación Espacial Herta',
|
es='Estación Espacial Herta',
|
||||||
|
world_id=0,
|
||||||
|
short_name='Herta',
|
||||||
)
|
)
|
||||||
Jarilo_VI = MapWorld(
|
Jarilo_VI = MapWorld(
|
||||||
id=2,
|
id=2,
|
||||||
@ -20,6 +22,8 @@ Jarilo_VI = MapWorld(
|
|||||||
en='Jarilo-VI',
|
en='Jarilo-VI',
|
||||||
jp='ヤリーロ-VI',
|
jp='ヤリーロ-VI',
|
||||||
es='Jarilo-VI',
|
es='Jarilo-VI',
|
||||||
|
world_id=1,
|
||||||
|
short_name='Jarilo',
|
||||||
)
|
)
|
||||||
The_Xianzhou_Luofu = MapWorld(
|
The_Xianzhou_Luofu = MapWorld(
|
||||||
id=3,
|
id=3,
|
||||||
@ -29,4 +33,17 @@ The_Xianzhou_Luofu = MapWorld(
|
|||||||
en='The Xianzhou Luofu',
|
en='The Xianzhou Luofu',
|
||||||
jp='仙舟「羅浮」',
|
jp='仙舟「羅浮」',
|
||||||
es='El Luofu de Xianzhou',
|
es='El Luofu de Xianzhou',
|
||||||
|
world_id=2,
|
||||||
|
short_name='Luofu',
|
||||||
|
)
|
||||||
|
Penacony = MapWorld(
|
||||||
|
id=4,
|
||||||
|
name='Penacony',
|
||||||
|
cn='匹诺康尼',
|
||||||
|
cht='匹諾康尼',
|
||||||
|
en='Penacony',
|
||||||
|
jp='ピノコニー',
|
||||||
|
es='Colonipenal',
|
||||||
|
world_id=3,
|
||||||
|
short_name='Penacony',
|
||||||
)
|
)
|
||||||
|
@ -79,9 +79,9 @@ class MapResource(ResourceConst):
|
|||||||
@cached_property
|
@cached_property
|
||||||
def assets_file_basename(self):
|
def assets_file_basename(self):
|
||||||
if self.plane.has_multiple_floors or self.is_special_plane:
|
if self.plane.has_multiple_floors or self.is_special_plane:
|
||||||
return f'./position/{self.plane.world}/{self.plane.name}_{self.floor}'
|
return f'./position/{self.plane.world.short_name}/{self.plane.name}_{self.floor}'
|
||||||
else:
|
else:
|
||||||
return f'./position/{self.plane.world}/{self.plane.name}'
|
return f'./position/{self.plane.world.short_name}/{self.plane.name}'
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def assets_floor(self):
|
def assets_floor(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user