Files
dcalc/backend/api/utils/skill_detail.py
T
2026-06-02 20:56:07 +08:00

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