61 lines
1.7 KiB
Python
61 lines
1.7 KiB
Python
from copy import deepcopy
|
|
import re
|
|
from typing import Any
|
|
|
|
|
|
PLACEHOLDER_PATTERN = re.compile(r'<(?:int|float\d*)[^>]*>')
|
|
VALUE_PATTERN = re.compile(r'\{value\d+\}')
|
|
|
|
|
|
def replace_placeholders(template: str) -> str:
|
|
idx = 0
|
|
|
|
def repl(_: re.Match[str]) -> str:
|
|
nonlocal idx
|
|
idx += 1
|
|
return f'{{value{idx}}}'
|
|
|
|
return PLACEHOLDER_PATTERN.sub(repl, template)
|
|
|
|
|
|
def normalize_skill_detail(skill_data: dict[str, Any]) -> dict[str, Any]:
|
|
level_info = skill_data.get('levelInfo')
|
|
if not isinstance(level_info, dict):
|
|
return skill_data
|
|
|
|
option_desc = level_info.get('optionDesc')
|
|
if option_desc is not None:
|
|
level_info['optionDesc'] = replace_placeholders(option_desc)
|
|
return skill_data
|
|
|
|
|
|
def skill_detail_for_level(skill_data: dict[str, Any], level: int | None) -> dict[str, Any]:
|
|
result = deepcopy(skill_data)
|
|
if level is None:
|
|
return result
|
|
|
|
level = max(0, min(level, result.get('maxLevel', 0)))
|
|
level_info = result.get('levelInfo')
|
|
if not isinstance(level_info, dict):
|
|
return result
|
|
|
|
rows = level_info.get('rows')
|
|
if not isinstance(rows, list):
|
|
return result
|
|
|
|
detail = next((row for row in rows if row.get('level') == level), None)
|
|
if not detail:
|
|
return result
|
|
|
|
attribute = {**level_info, **detail}
|
|
attribute['detail'] = attribute.get('optionDesc', '')
|
|
|
|
for key, value in (attribute.get('optionValue') or {}).items():
|
|
attribute['detail'] = attribute['detail'].replace(f'{{{key}}}', str(value))
|
|
attribute['detail'] = VALUE_PATTERN.sub('-', attribute['detail'])
|
|
|
|
attribute.pop('rows', None)
|
|
result['attribute'] = attribute
|
|
result.pop('levelInfo', None)
|
|
return result
|