feat(config-editor): port buildSkillDesc to JS for panel preview

This commit is contained in:
panFD
2026-06-21 09:17:50 +08:00
parent 4a5659b7ec
commit 6a81630f6f
2 changed files with 88 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
import { RecordValue } from '../../io/recordValue';
const TRIGGER_KEYS = ['call', 'dead', 'fstart', 'fend', 'atking', 'atked'] as const;
const TRIGGER_DESC: Record<string, string> = {
call: '召唤时', dead: '死亡时', fstart: '战斗开始时', fend: '战斗结束时',
field: '场上存活', atking: '攻击n次', atked: '受击n次', revive: '复活时',
};
function num(v: RecordValue | undefined): number | undefined { return v && v.kind === 'num' ? v.value : undefined; }
function str(v: RecordValue | undefined): string | undefined { return v && v.kind === 'str' ? v.value : undefined; }
function member(v: RecordValue | undefined): string | undefined { return v && v.kind === 'enumRef' ? v.member : undefined; }
function buildEffect(merged: RecordValue): string {
if (merged.kind !== 'obj') return '';
const kind = member(merged.props['kind']);
const ap = num(merged.props['ap']) ?? 0;
const parts: string[] = [];
if (kind === 'Heal') parts.push(`治疗伙伴${ap}`);
else if (kind === 'Shield') parts.push(`护盾${ap}`);
else if (kind === 'Gold') parts.push(`金币+${num(merged.props['gold']) ?? 0}`);
else if (kind === 'Support') parts.push(String(str(merged.props['info']) ?? ''));
else { // Damage / undefined
parts.push(`伤害${ap}%`);
if ((num(merged.props['hit_count']) ?? 1) > 1) parts.push(`${num(merged.props['hit_count'])}`);
if (num(merged.props['crt'])) parts.push(`暴击+${num(merged.props['crt'])}%`);
if (num(merged.props['stun'])) parts.push(`击晕+${num(merged.props['stun'])}%`);
}
return parts.join(' ');
}
/** 合并 overrides 到 base浅合并对象 props */
function merge(base: RecordValue, overrides: RecordValue | undefined): RecordValue {
if (!overrides || overrides.kind !== 'obj' || base.kind !== 'obj') return base;
return { kind: 'obj', props: { ...base.props, ...overrides.props } };
}
export function buildSkillDesc(hero: RecordValue, skillSet: Record<number, RecordValue>, fieldSet: Record<number, RecordValue>): string {
if (hero.kind !== 'obj') return '';
const lines: string[] = [];
for (const key of TRIGGER_KEYS) {
const arr = hero.props[key];
if (!arr || arr.kind !== 'arr') continue;
const tpl = TRIGGER_DESC[key] ?? key;
for (const it of arr.items) {
if (it.kind !== 'obj') continue;
const su = num(it.props['s_uuid']); if (su === undefined) continue;
const base = skillSet[su]; if (!base) continue;
const merged = merge(base, it.props['overrides']);
const trigger = tpl.includes('n') ? tpl.replace('n', String(num(it.props['t_num']) ?? '')) : tpl;
lines.push(`${trigger}:${str(base.props['name'])} ${buildEffect(merged)}`);
}
}
const fl = hero.props['field'];
if (fl && fl.kind === 'arr') {
for (const it of fl.items) { const u = num(it); if (u === undefined) continue; const fs = fieldSet[u]; if (fs) lines.push(`${TRIGGER_DESC.field}:${str(fs.props['name'])} ${str(fs.props['info'])}`); }
}
const rv = hero.props['revive'];
if (rv && rv.kind === 'obj') {
const su = num(rv.props['s_uuid']); const base = su !== undefined ? skillSet[su] : undefined;
if (base) lines.push(`${TRIGGER_DESC.revive} : ${str(base.props['name'])} ${buildEffect(merge(base, undefined))}`);
}
return lines.join('\n');
}