Compare commits
2 Commits
d0971ff72c
...
1b1244c33c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b1244c33c | ||
|
|
57c7934571 |
@@ -23,12 +23,12 @@
|
|||||||
* 字段结构一致,天然都满足。HeroBoxComp 传 model 显示当前等级;卡池/商店传 heroInfo 显示 1 级。
|
* 字段结构一致,天然都满足。HeroBoxComp 传 model 显示当前等级;卡池/商店传 heroInfo 显示 1 级。
|
||||||
*
|
*
|
||||||
* 依赖:
|
* 依赖:
|
||||||
* - heroSet :SkillTriggerName、SkillTriggerType、HeroEvolve
|
* - heroSet :SkillTriggerName、SkillTriggerType、TriggerGrouped/LvFieldEntry/LvReviveEntry/LvBonusEntry 及 resolver
|
||||||
* - SkillSet :SkillSet、mergeSkillParams、SkillOverrides、SkillKind、TGroup
|
* - SkillSet :SkillSet、mergeSkillParams、SkillOverrides、SkillKind、TGroup
|
||||||
* - SkillDescSet:结构化描述模板
|
* - SkillDescSet:结构化描述模板
|
||||||
* - FieldSkillSet(驻场技能)、BuffList(计时 buff 默认值兜底)、Attrs(属性枚举)
|
* - FieldSkillSet(驻场技能)、BuffList(计时 buff 默认值兜底)、Attrs(属性枚举)
|
||||||
*/
|
*/
|
||||||
import { HeroEvolve, SkillTriggerName, SkillTriggerType } from "./heroSet";
|
import { SkillTriggerName, SkillTriggerType, TriggerGrouped, LvTriggerEntry, LvFieldEntry, LvReviveEntry, LvBonusEntry, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv } from "./heroSet";
|
||||||
import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides, SkillSet, TGroup } from "./SkillSet";
|
import { FieldSkillSet, mergeSkillParams, SkillConfig, SkillKind, SkillOverrides, SkillSet, TGroup } from "./SkillSet";
|
||||||
import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet";
|
import { FieldDescSet, FieldValueFmt, SkillDescSet } from "./SkillDescSet";
|
||||||
import { BuffList } from "./BuffSet";
|
import { BuffList } from "./BuffSet";
|
||||||
@@ -37,21 +37,22 @@ import { CardConfig } from "./CardSet";
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成器入参窄接口:只约束实际读取的字段。
|
* 生成器入参窄接口:只约束实际读取的字段。
|
||||||
* heroInfo 与 HeroAttrsComp 的对应字段结构完全一致,天然都满足此接口。
|
* heroInfo 与 HeroAttrsComp 的对应字段结构完全一致(均为分组 + lv 数组),天然都满足此接口。
|
||||||
*/
|
*/
|
||||||
export interface ISkillDescSource {
|
export interface ISkillDescSource {
|
||||||
/** 当前等级(用于计算 revive 实际复活次数、evolve 累计加成;静态 heroInfo 恒为 1) */
|
/** 当前等级(用于 resolve 触发技能/光环/复活取档;静态 heroInfo 恒为 1) */
|
||||||
lv?: number;
|
lv?: number;
|
||||||
call?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
call?: TriggerGrouped;
|
||||||
dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
dead?: TriggerGrouped;
|
||||||
fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
fstart?: TriggerGrouped;
|
||||||
fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
fend?: TriggerGrouped;
|
||||||
atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
atking?: TriggerGrouped;
|
||||||
atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
atked?: TriggerGrouped;
|
||||||
field?: number[];
|
field?: LvFieldEntry[];
|
||||||
revive?: { s_uuid: number; r_num: number; upr: number };
|
revive?: LvReviveEntry[];
|
||||||
/** 等级进化配置(heroInfo 自带;HeroAttrsComp 记录快照),用于累计 ap/hp 额外加成文案 */
|
/** 额外攻击/生命加成(按 lv 累加,用于成长文案) */
|
||||||
evolve?: Record<number, HeroEvolve>;
|
ap_bonus?: LvBonusEntry[];
|
||||||
|
hp_bonus?: LvBonusEntry[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -65,6 +66,10 @@ interface ISkillLine {
|
|||||||
value: string;
|
value: string;
|
||||||
/** 数值后的文本(如 ",持续5秒" 之类尾部补充) */
|
/** 数值后的文本(如 ",持续5秒" 之类尾部补充) */
|
||||||
suffix: string;
|
suffix: string;
|
||||||
|
/** 尚未激活(档位等级高于当前等级):富文本整行灰色、不做高亮 */
|
||||||
|
locked?: boolean;
|
||||||
|
/** 同一技能未来档位的数值列表(全档位合并模式专用):渲染为 value 后灰色 "/v1/v2" 拼接 */
|
||||||
|
nextValues?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 需要遍历的触发技能类型列表(不含 Field 和 Revive,这两者结构不同需单独处理) */
|
/** 需要遍历的触发技能类型列表(不含 Field 和 Revive,这两者结构不同需单独处理) */
|
||||||
@@ -89,6 +94,9 @@ const RICH_VALUE_COLOR = "#27AE60";
|
|||||||
/** 富文本技能名高亮色(蓝色,与数值绿色区分,标识技能名「」片段) */
|
/** 富文本技能名高亮色(蓝色,与数值绿色区分,标识技能名「」片段) */
|
||||||
const RICH_NAME_COLOR = "#2E86C1";
|
const RICH_NAME_COLOR = "#2E86C1";
|
||||||
|
|
||||||
|
/** 富文本未激活档位整行灰色(低饱和,深色面板上可读但明显弱化) */
|
||||||
|
const RICH_LOCKED_COLOR = "#95A5A6";
|
||||||
|
|
||||||
/** 技能名「」匹配模式(仅本模块行首/行中技能名片段使用) */
|
/** 技能名「」匹配模式(仅本模块行首/行中技能名片段使用) */
|
||||||
const SKILL_NAME_PATTERN = /「([^」]*)」/g;
|
const SKILL_NAME_PATTERN = /「([^」]*)」/g;
|
||||||
|
|
||||||
@@ -228,37 +236,81 @@ function buildFieldLine(head: string, uuid: number, showName: boolean = true): I
|
|||||||
/**
|
/**
|
||||||
* 复活(revive)结构化行:复刻战斗公式,高亮复活次数与回血百分比
|
* 复活(revive)结构化行:复刻战斗公式,高亮复活次数与回血百分比
|
||||||
* 复活次数 = r_num + floor((lv - 1) * upr);回血百分比 = SkillSet[s_uuid].ap
|
* 复活次数 = r_num + floor((lv - 1) * upr);回血百分比 = SkillSet[s_uuid].ap
|
||||||
|
*
|
||||||
|
* @param showLocked true 时列出全部档位并标激活状态(未激活档位次数按解锁等级预估);
|
||||||
|
* false 时仅输出当前等级生效档
|
||||||
*/
|
*/
|
||||||
function buildReviveLine(source: ISkillDescSource, showName: boolean = true): ISkillLine | null {
|
function buildReviveLines(source: ISkillDescSource, showName: boolean = true, showLocked: boolean = false): ISkillLine[] {
|
||||||
const revive = source.revive;
|
|
||||||
if (!revive) return null;
|
|
||||||
const base = SkillSet[revive.s_uuid];
|
|
||||||
if (!base) return null;
|
|
||||||
const lv = Math.max(1, source.lv ?? 1);
|
const lv = Math.max(1, source.lv ?? 1);
|
||||||
const maxCount = revive.r_num + Math.floor((lv - 1) * revive.upr);
|
const entries = source.revive;
|
||||||
const hpPct = base.ap ?? 0;
|
if (!entries?.length) return [];
|
||||||
|
|
||||||
const tpl = SkillTriggerName[SkillTriggerType.Revive] ?? "复活";
|
const tpl = SkillTriggerName[SkillTriggerType.Revive] ?? "复活";
|
||||||
const nameSeg = showName ? `「${base.name}」 ` : "";
|
const makeLine = (entry: { s_uuid: number; r_num: number; upr: number }, head: string, countLv: number, locked: boolean): ISkillLine | null => {
|
||||||
// 高亮片段选回血百分比(数值中最关键的收益指标)
|
const base = SkillSet[entry.s_uuid];
|
||||||
return {
|
if (!base) return null;
|
||||||
prefix: `${tpl}:${nameSeg}可复活${maxCount}次,每次恢复`,
|
const maxCount = entry.r_num + Math.floor((countLv - 1) * entry.upr);
|
||||||
value: `${hpPct}%`,
|
const hpPct = base.ap ?? 0;
|
||||||
suffix: "生命",
|
const nameSeg = showName ? `「${base.name}」 ` : "";
|
||||||
|
// 高亮片段选回血百分比(数值中最关键的收益指标)
|
||||||
|
return {
|
||||||
|
prefix: `${head}${nameSeg}可复活${maxCount}次,每次恢复`,
|
||||||
|
value: `${hpPct}%`,
|
||||||
|
suffix: "生命",
|
||||||
|
locked,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!showLocked) {
|
||||||
|
const revive = resolveReviveByLv(entries, lv);
|
||||||
|
if (!revive) return [];
|
||||||
|
const line = makeLine(revive, `${tpl}:`, lv, false);
|
||||||
|
return line ? [line] : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全档位合并模式:每个 s_uuid 只出一行,等级前缀置前("Lv2: 复活 ...")
|
||||||
|
const groups: Record<number, LvReviveEntry[]> = {};
|
||||||
|
for (const e of entries) {
|
||||||
|
(groups[e.s_uuid] ??= []).push(e);
|
||||||
|
}
|
||||||
|
const lines: ISkillLine[] = [];
|
||||||
|
for (const key in groups) {
|
||||||
|
const sorted = [...groups[Number(key)]].sort((a, b) => a.lv - b.lv);
|
||||||
|
let active: LvReviveEntry | undefined;
|
||||||
|
for (const e of sorted) { if (e.lv <= lv) active = e; }
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
const line = makeLine(active, `Lv${active.lv}: ${tpl} `, lv, false);
|
||||||
|
if (!line) continue;
|
||||||
|
// 未来档回血数值以灰色追加(同 s_uuid 的 base.ap 通常相同,仅不同时才拼接)
|
||||||
|
const nextVals: string[] = [];
|
||||||
|
for (const e of sorted) {
|
||||||
|
if (e.lv <= lv) continue;
|
||||||
|
const v = `${SkillSet[e.s_uuid]?.ap ?? 0}%`;
|
||||||
|
if (v !== line.value && !nextVals.includes(v)) nextVals.push(v);
|
||||||
|
}
|
||||||
|
if (nextVals.length) line.nextValues = nextVals;
|
||||||
|
lines.push(line);
|
||||||
|
} else {
|
||||||
|
// 完全未激活:预览最低档,次数按解锁等级预估,整行灰色
|
||||||
|
const first = sorted[0];
|
||||||
|
const line = makeLine(first, `Lv${first.lv}: ${tpl} `, first.lv, true);
|
||||||
|
if (line) lines.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** evolve 额外属性加成(ap/hp)累计结构化行:高亮累计数值 */
|
/** 额外属性加成(ap/hp)累计结构化行:高亮累计数值 */
|
||||||
function buildEvolveBonusLines(source: ISkillDescSource): ISkillLine[] {
|
function buildEvolveBonusLines(source: ISkillDescSource): ISkillLine[] {
|
||||||
const evolve = source.evolve;
|
|
||||||
if (!evolve) return [];
|
|
||||||
const lv = Math.max(1, source.lv ?? 1);
|
const lv = Math.max(1, source.lv ?? 1);
|
||||||
let apTotal = 0;
|
let apTotal = 0;
|
||||||
let hpTotal = 0;
|
let hpTotal = 0;
|
||||||
for (let elv = 2; elv <= lv; elv++) {
|
if (source.ap_bonus) {
|
||||||
const evo = evolve[elv];
|
for (const e of source.ap_bonus) { if (e.lv <= lv) apTotal += e.value; }
|
||||||
if (!evo) continue;
|
}
|
||||||
apTotal += evo.ap_bonus ?? 0;
|
if (source.hp_bonus) {
|
||||||
hpTotal += evo.hp_bonus ?? 0;
|
for (const e of source.hp_bonus) { if (e.lv <= lv) hpTotal += e.value; }
|
||||||
}
|
}
|
||||||
const lines: ISkillLine[] = [];
|
const lines: ISkillLine[] = [];
|
||||||
if (apTotal !== 0) lines.push({ prefix: "成长:额外", value: `+${apTotal}`, suffix: ATTR_NAME[Attrs.ap] ?? "攻击力" });
|
if (apTotal !== 0) lines.push({ prefix: "成长:额外", value: `+${apTotal}`, suffix: ATTR_NAME[Attrs.ap] ?? "攻击力" });
|
||||||
@@ -267,46 +319,112 @@ function buildEvolveBonusLines(source: ISkillDescSource): ISkillLine[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建全部能力结构化行(触发技能 + 驻场光环 + 复活 + evolve 加成)。
|
* 构建全部能力结构化行(触发技能 + 驻场光环 + 复活 + 额外加成)。
|
||||||
* 纯文本与富文本两个公开接口共用此结果,仅渲染阶段不同。
|
* 纯文本与富文本两个公开接口共用此结果,仅渲染阶段不同。
|
||||||
* @param showName 是否在行中包含「技能名」片段(英雄盒面板传 false 隐藏技能名)
|
*
|
||||||
|
* @param showName 是否在行中包含「技能名」片段
|
||||||
|
* @param showLocked true 时为全档位合并模式:每个技能只出一行——已激活档正常渲染且
|
||||||
|
* 未来档数值灰色拼接在 value 后(nextValues);完全未激活的技能
|
||||||
|
* 预览最低档、整行 locked 灰色、Lv 前缀置前。false 时仅输出当前生效档
|
||||||
*/
|
*/
|
||||||
function buildSkillLines(source: ISkillDescSource, showName: boolean = true): ISkillLine[] {
|
function buildSkillLines(source: ISkillDescSource, showName: boolean = true, showLocked: boolean = false): ISkillLine[] {
|
||||||
const lines: ISkillLine[] = [];
|
const lines: ISkillLine[] = [];
|
||||||
|
const lv = Math.max(1, source.lv ?? 1);
|
||||||
|
|
||||||
// ---- 6 种标准触发技能 ----
|
// ---- 6 种标准触发技能 ----
|
||||||
for (const key of TRIGGER_KEYS) {
|
for (const key of TRIGGER_KEYS) {
|
||||||
const arr = source[key] as { s_uuid: number; t_num: number; overrides?: SkillOverrides }[] | undefined;
|
const grouped = source[key] as TriggerGrouped | undefined;
|
||||||
if (!arr?.length) continue;
|
if (!grouped) continue;
|
||||||
// 触发类型简称(召唤/亡语/起手/生息/进击/受击)
|
// 触发类型简称(召唤/亡语/起手/生息/进击/受击)
|
||||||
const name = SkillTriggerName[key] ?? key;
|
const name = SkillTriggerName[key] ?? key;
|
||||||
// 仅进击/受击带触发次数,拼为"×n";其余简称直接用
|
// 仅进击/受击带触发次数,拼为"×n";其余简称直接用
|
||||||
const needCount = key === SkillTriggerType.Atking || key === SkillTriggerType.Atked;
|
const needCount = key === SkillTriggerType.Atking || key === SkillTriggerType.Atked;
|
||||||
for (const item of arr) {
|
|
||||||
const base = SkillSet[item.s_uuid];
|
if (!showLocked) {
|
||||||
|
// 仅当前等级生效档(resolve 取各 s_uuid ≤lv 的最大档)
|
||||||
|
for (const item of resolveTriggerByLv(grouped, lv)) {
|
||||||
|
const base = SkillSet[item.s_uuid];
|
||||||
|
if (!base) continue;
|
||||||
|
const skill = mergeSkillParams(base, item.overrides);
|
||||||
|
const trigger = needCount ? `${name}×${item.t_num}` : name;
|
||||||
|
const nameSeg = showName ? `「${base.name}」 ` : "";
|
||||||
|
lines.push(buildEffectLine(`${trigger}:${nameSeg}`, skill));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全档位合并模式:每个 s_uuid 只出一行,等级前缀置前("Lv1: 进击×5 ...")
|
||||||
|
for (const sKey in grouped) {
|
||||||
|
const entries = grouped[sKey];
|
||||||
|
if (!entries?.length) continue;
|
||||||
|
const base = SkillSet[Number(sKey)];
|
||||||
if (!base) continue;
|
if (!base) continue;
|
||||||
const skill = mergeSkillParams(base, item.overrides);
|
const sorted = [...entries].sort((a, b) => a.lv - b.lv);
|
||||||
const trigger = needCount ? `${name}×${item.t_num}` : name;
|
|
||||||
const nameSeg = showName ? `「${base.name}」 ` : "";
|
const nameSeg = showName ? `「${base.name}」 ` : "";
|
||||||
lines.push(buildEffectLine(`${trigger}:${nameSeg}`, skill));
|
const headOf = (e: LvTriggerEntry) => `Lv${e.lv}: ${needCount ? `${name}×${e.t_num}` : name} ${nameSeg}`;
|
||||||
|
|
||||||
|
// 取当前等级生效档(≤lv 的最大档)
|
||||||
|
let active: LvTriggerEntry | undefined;
|
||||||
|
for (const e of sorted) { if (e.lv <= lv) active = e; }
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
const line = buildEffectLine(headOf(active), mergeSkillParams(base, active.overrides));
|
||||||
|
// 未来档数值以灰色 "/v1/v2" 追加在高亮数值后(仅收集与当前不同的数值,避免重复)
|
||||||
|
const nextVals: string[] = [];
|
||||||
|
for (const e of sorted) {
|
||||||
|
if (e.lv <= lv) continue;
|
||||||
|
const v = buildEffectLine("", mergeSkillParams(base, e.overrides)).value;
|
||||||
|
if (v && v !== line.value && !nextVals.includes(v)) nextVals.push(v);
|
||||||
|
}
|
||||||
|
if (nextVals.length) line.nextValues = nextVals;
|
||||||
|
lines.push(line);
|
||||||
|
} else {
|
||||||
|
// 技能完全未激活:预览最低档效果,整行灰色
|
||||||
|
const first = sorted[0];
|
||||||
|
const line = buildEffectLine(headOf(first), mergeSkillParams(base, first.overrides));
|
||||||
|
line.locked = true;
|
||||||
|
lines.push(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- 驻场光环(field):查 FieldDescSet 结构化渲染,value 数值高亮 ----
|
// ---- 驻场光环(field):查 FieldDescSet 结构化渲染,value 数值高亮 ----
|
||||||
const fieldUuids = source[SkillTriggerType.Field] as number[] | undefined;
|
const fieldEntries = source[SkillTriggerType.Field] as LvFieldEntry[] | undefined;
|
||||||
if (fieldUuids?.length) {
|
if (fieldEntries?.length) {
|
||||||
const tpl = SkillTriggerName[SkillTriggerType.Field] ?? "光环";
|
const tpl = SkillTriggerName[SkillTriggerType.Field] ?? "光环";
|
||||||
for (const uuid of fieldUuids) {
|
if (!showLocked) {
|
||||||
const line = buildFieldLine(`${tpl}:`, uuid, showName);
|
for (const uuid of resolveFieldByLv(fieldEntries, lv)) {
|
||||||
if (line) lines.push(line);
|
const line = buildFieldLine(`${tpl}:`, uuid, showName);
|
||||||
|
if (line) lines.push(line);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 全档位合并模式:生效档(≤lv 最大档)正常显示,未来档整行灰色且 Lv 置前;
|
||||||
|
// 被替换的历史档不显示(resolve 语义下升级后旧档光环失效)
|
||||||
|
const sorted = [...fieldEntries].sort((a, b) => a.lv - b.lv);
|
||||||
|
let activeTier: LvFieldEntry | undefined;
|
||||||
|
for (const tier of sorted) { if (tier.lv <= lv) activeTier = tier; }
|
||||||
|
if (activeTier) {
|
||||||
|
for (const uuid of activeTier.uuids) {
|
||||||
|
const line = buildFieldLine(`Lv${activeTier.lv}: ${tpl} `, uuid, showName);
|
||||||
|
if (line) lines.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const tier of sorted) {
|
||||||
|
if (tier.lv <= lv) continue;
|
||||||
|
for (const uuid of tier.uuids) {
|
||||||
|
const line = buildFieldLine(`Lv${tier.lv}: ${tpl} `, uuid, showName);
|
||||||
|
if (!line) continue;
|
||||||
|
line.locked = true;
|
||||||
|
lines.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- 复活(revive)----
|
// ---- 复活(revive)----
|
||||||
const reviveLine = buildReviveLine(source, showName);
|
lines.push(...buildReviveLines(source, showName, showLocked));
|
||||||
if (reviveLine) lines.push(reviveLine);
|
|
||||||
|
|
||||||
// ---- evolve 额外属性加成(ap/hp)----
|
// ---- 额外属性加成(ap/hp,按当前等级累计)----
|
||||||
lines.push(...buildEvolveBonusLines(source));
|
lines.push(...buildEvolveBonusLines(source));
|
||||||
|
|
||||||
return lines;
|
return lines;
|
||||||
@@ -325,20 +443,17 @@ export function buildSkillDesc(source: ISkillDescSource): string {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 富文本描述(RichText 用,BBCode):技能名用 <color=#2E86C1> 蓝色、数值用 <color=#27AE60> 亮绿色高亮。
|
* 富文本描述(RichText 用,BBCode):技能名用 <color=#2E86C1> 蓝色、数值用 <color=#27AE60> 亮绿色高亮。
|
||||||
* @param source 触发技能数据源(同 buildSkillDesc)
|
* @param source 触发技能数据源(同 buildSkillDesc)
|
||||||
* @param showName 是否包含「技能名」片段(英雄盒面板传 false 隐藏技能名,默认 true)
|
* @param showName 是否包含「技能名」片段(默认 true)
|
||||||
* @returns 多行富文本串,技能名片段包裹 <color=#2E86C1>、数值片段包裹 <color=#27AE60>,用 \n 分隔
|
* @param showLocked true 时为全档位合并模式:每个技能只出一行,已激活档数值高亮、
|
||||||
|
* 未来档数值灰色 "/v1/v2" 追加;完全未激活的技能整行灰色且 Lv 前缀置前
|
||||||
|
* (英雄盒面板用);false 时仅输出当前等级生效档
|
||||||
|
* @returns 多行富文本串,用 \n 分隔
|
||||||
*/
|
*/
|
||||||
export function buildSkillDescRich(source: ISkillDescSource, showName: boolean = true): string {
|
export function buildSkillDescRich(source: ISkillDescSource, showName: boolean = true, showLocked: boolean = false): string {
|
||||||
return buildSkillLines(source, showName)
|
return buildSkillLines(source, showName, showLocked)
|
||||||
.map(l => {
|
// 未激活行保持整行灰色,不再补充"持续X秒"数值高亮
|
||||||
const prefix = l.prefix.replace(SKILL_NAME_PATTERN, `「<color=${RICH_NAME_COLOR}>$1</color>」`);
|
.map(l => l.locked ? renderLineRich(l) : highlightDuration(renderLineRich(l)))
|
||||||
const text = l.value
|
|
||||||
? `${prefix}<color=${RICH_VALUE_COLOR}>${l.value}</color>${l.suffix}`
|
|
||||||
: `${prefix}${l.suffix}`;
|
|
||||||
// 持续时间数值同样高亮(计时 buff 的"持续X秒")
|
|
||||||
return highlightDuration(text);
|
|
||||||
})
|
|
||||||
.join("\n");
|
.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,13 +515,17 @@ function highlightDuration(text: string): string {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 结构化行 → 富文本串(技能名蓝色、数值绿色)。
|
* 结构化行 → 富文本串(技能名蓝色、数值绿色)。
|
||||||
* buildEquipRich / buildCardDescRich 共用,保证渲染规则唯一。
|
* buildEquipRich / buildCardDescRich / buildSkillDescRich 共用,保证渲染规则唯一。
|
||||||
|
* 未激活行(locked)整行灰色弱化、不做技能名/数值高亮。
|
||||||
*/
|
*/
|
||||||
function renderLineRich(line: ISkillLine): string {
|
function renderLineRich(line: ISkillLine): string {
|
||||||
|
if (line.locked) return `<color=${RICH_LOCKED_COLOR}>${line.prefix}${line.value}${line.suffix}</color>`;
|
||||||
const prefix = line.prefix.replace(SKILL_NAME_PATTERN, `「<color=${RICH_NAME_COLOR}>$1</color>」`);
|
const prefix = line.prefix.replace(SKILL_NAME_PATTERN, `「<color=${RICH_NAME_COLOR}>$1</color>」`);
|
||||||
|
// 未来档数值灰色追加在当前高亮数值后("15%/20%/30%"),suffix 仍位于整段数值之后
|
||||||
|
const next = line.nextValues?.length ? `<color=${RICH_LOCKED_COLOR}>/${line.nextValues.join("/")}</color>` : "";
|
||||||
return line.value
|
return line.value
|
||||||
? `${prefix}<color=${RICH_VALUE_COLOR}>${line.value}</color>${line.suffix}`
|
? `${prefix}<color=${RICH_VALUE_COLOR}>${line.value}</color>${next}${line.suffix}`
|
||||||
: `${prefix}${line.suffix}`;
|
: `${prefix}${next}${line.suffix}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -161,18 +161,19 @@ export interface heroInfo {
|
|||||||
monType?: MonType; // 怪物专属类型
|
monType?: MonType; // 怪物专属类型
|
||||||
hp: number; // 生命值上限
|
hp: number; // 生命值上限
|
||||||
ap: number; // 攻击力
|
ap: number; // 攻击力
|
||||||
[SkillTriggerType.Call]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 召唤后触发的技能配置
|
[SkillTriggerType.Call]?: TriggerGrouped; // 召唤后触发的技能配置(按 s_uuid 分组,每组按 lv 升序)
|
||||||
[SkillTriggerType.Dead]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 死亡后触发的技能配置
|
[SkillTriggerType.Dead]?: TriggerGrouped; // 死亡后触发的技能配置
|
||||||
[SkillTriggerType.FStart]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 战斗开始时释放的技能配置
|
[SkillTriggerType.FStart]?: TriggerGrouped; // 战斗开始时释放的技能配置
|
||||||
[SkillTriggerType.FEnd]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 战斗结束时释放的技能配置
|
[SkillTriggerType.FEnd]?: TriggerGrouped; // 战斗结束时释放的技能配置
|
||||||
[SkillTriggerType.Field]?: number[]; // 驻场技能uuid列表,英雄在场时对全局生效
|
[SkillTriggerType.Field]?: LvFieldEntry[]; // 驻场光环(按 lv 升序,运行时取 ≤英雄等级 的最大档)
|
||||||
[SkillTriggerType.Atking]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数
|
[SkillTriggerType.Atking]?: TriggerGrouped; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数
|
||||||
[SkillTriggerType.Atked]?: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[]; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数
|
[SkillTriggerType.Atked]?: TriggerGrouped; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数
|
||||||
[SkillTriggerType.Revive]?: { s_uuid: number, r_num: number, upr: number }; // 复活技能配置,s_uuid: 技能id, r_num: 触发所需的复活次数, upr 等级对复活次数的影响
|
[SkillTriggerType.Revive]?: LvReviveEntry[]; // 复活技能配置(按 lv 升序,运行时取 ≤英雄等级 的最大档)
|
||||||
dis?: number; // 攻击距离(像素)
|
dis?: number; // 攻击距离(像素)
|
||||||
speed?: number; // 移动速度(像素/秒)
|
speed?: number; // 移动速度(像素/秒)
|
||||||
skills: Record<number, HSkillInfo>; // 携带技能ID列表
|
skills: Record<number, HSkillInfo>; // 携带技能ID列表
|
||||||
evolve?: Record<number, HeroEvolve>; // 等级进化配置,key=等级(2,3,...)
|
ap_bonus?: LvBonusEntry[]; // 额外攻击加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档)
|
||||||
|
hp_bonus?: LvBonusEntry[]; // 额外生命加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档)
|
||||||
info: string; // 描述文案
|
info: string; // 描述文案
|
||||||
/** 分级能力说明,索引0=1级,依次递增;信息面板逐条展示各等级技能与能力 */
|
/** 分级能力说明,索引0=1级,依次递增;信息面板逐条展示各等级技能与能力 */
|
||||||
infos?: string[];
|
infos?: string[];
|
||||||
@@ -187,25 +188,46 @@ export interface HSkillInfo {
|
|||||||
ccd: number; // 占位当前cd,用于cd计时
|
ccd: number; // 占位当前cd,用于cd计时
|
||||||
overrides?: SkillOverrides; // 角色专属参数覆盖
|
overrides?: SkillOverrides; // 角色专属参数覆盖
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 英雄等级进化配置
|
* 触发技能单档配置:达到 lv 级时此档参数生效(t_num/overrides 可随等级变化)。
|
||||||
* 定义英雄在某等级时技能/属性的变化
|
|
||||||
*/
|
*/
|
||||||
export interface HeroEvolve {
|
export interface LvTriggerEntry {
|
||||||
/** 替换普攻技能(清除旧技能,添加新技能) */
|
lv: number; // 达到该英雄等级时解锁此档
|
||||||
skill?: { s_uuid: number; cd?: number; overrides?: SkillOverrides };
|
t_num: number;
|
||||||
/** 覆盖触发技能(完全替换该类型的触发配置) */
|
overrides?: SkillOverrides;
|
||||||
atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
}
|
||||||
atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
|
||||||
dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
/**
|
||||||
fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
* 触发技能按 s_uuid 分组的配置:每个 s_uuid 下按 lv 升序排列。
|
||||||
fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
* 运行时取每个 s_uuid 中 ≤英雄等级 的最大 lv 档。
|
||||||
/** 覆盖驻场光环(FieldSkillSet uuid 列表,存活期间全局生效) */
|
*/
|
||||||
field?: number[];
|
export type TriggerGrouped = Record<number /*s_uuid*/, LvTriggerEntry[]>;
|
||||||
revive?: { s_uuid: number; r_num: number; upr: number };
|
|
||||||
/** 额外属性加成(在等级倍率基础上叠加) */
|
/**
|
||||||
ap_bonus?: number;
|
* 驻场光环按等级解锁:运行时取 ≤英雄等级 的最大 lv 档的 uuids。
|
||||||
hp_bonus?: number;
|
*/
|
||||||
|
export interface LvFieldEntry {
|
||||||
|
lv: number;
|
||||||
|
uuids: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复活技能按等级解锁:运行时取 ≤英雄等级 的最大 lv 档。
|
||||||
|
*/
|
||||||
|
export interface LvReviveEntry {
|
||||||
|
lv: number;
|
||||||
|
s_uuid: number;
|
||||||
|
r_num: number;
|
||||||
|
upr: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 额外属性加成按等级叠加:运行时累加所有 ≤英雄等级 的档位。
|
||||||
|
*/
|
||||||
|
export interface LvBonusEntry {
|
||||||
|
lv: number;
|
||||||
|
value: number;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
*=============英雄配置列表================
|
*=============英雄配置列表================
|
||||||
@@ -228,133 +250,124 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5011: {
|
5011: {
|
||||||
uuid: 5011, name: "小铁卫", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
uuid: 5011, name: "小铁卫", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }],
|
|
||||||
// 成长主线:护盾层数 4→5→6(等效减伤 57%→67%),6 级追加治疗形成“盾挡+回血”双循环
|
// 成长主线:护盾层数 4→5→6(等效减伤 57%→67%),6 级追加治疗形成“盾挡+回血”双循环
|
||||||
// 注意:evolve.atked 为整体替换且逐级顺序应用,高级别需写完整数组
|
atked: {
|
||||||
evolve: {
|
6301: [
|
||||||
2: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }] },
|
{ lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } },
|
||||||
3: { hp_bonus: 150 },
|
{ lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } },
|
||||||
4: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 6 } }] },
|
{ lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 6 } },
|
||||||
5: { hp_bonus: 150, ap_bonus: 10 },
|
],
|
||||||
6: {
|
6302: [
|
||||||
atked: [
|
{ lv: 6, t_num: 5, overrides: { TGroup: TGroup.All, ap: 250 } },
|
||||||
{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 6 } },
|
],
|
||||||
{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.All, ap: 250 } },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 150 }, { lv: 5, value: 150 }],
|
||||||
|
ap_bonus: [{ lv: 5, value: 10 }],
|
||||||
info: "<color=#27AE60>✧</color>受伤获得护盾\n<color=#9B59B6>✦</color>受伤全队恢复生命",
|
info: "<color=#27AE60>✧</color>受伤获得护盾\n<color=#9B59B6>✦</color>受伤全队恢复生命",
|
||||||
},
|
},
|
||||||
5012: {
|
5012: {
|
||||||
uuid: 5012, name: "不死小强", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
uuid: 5012, name: "不死小强", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
atked: [
|
atked: {
|
||||||
{ s_uuid: 6302, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 250 } },
|
6302: [
|
||||||
{ s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
|
{ lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 250 } },
|
||||||
],
|
{ lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 300 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 350 } },
|
||||||
2: { atked: [{ s_uuid: 6302, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 300 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] },
|
{ lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 350 } },
|
||||||
3: { hp_bonus: 150 },
|
],
|
||||||
4: { atked: [{ s_uuid: 6302, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 350 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] },
|
6402: [
|
||||||
5: { atked: [{ s_uuid: 6302, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 350 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
|
||||||
6: {
|
],
|
||||||
atked: [
|
6301: [
|
||||||
{ s_uuid: 6302, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 350 } },
|
{ lv: 6, t_num: 5, overrides: { TGroup: TGroup.All, ap: 4 } },
|
||||||
{ s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
|
],
|
||||||
{ s_uuid: 6301, t_num: 5, overrides: { TGroup: TGroup.All, ap: 4 } },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 150 }],
|
||||||
info: "<color=#27AE60>✧</color>受伤恢复生命\n<color=#9B59B6>✦</color>受伤全体获得护盾",
|
info: "<color=#27AE60>✧</color>受伤恢复生命\n<color=#9B59B6>✦</color>受伤全体获得护盾",
|
||||||
},
|
},
|
||||||
5013: {
|
5013: {
|
||||||
uuid: 5013, name: "铁骨头", path: "hk4", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
uuid: 5013, name: "铁骨头", path: "hk4", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
atked: [
|
atked: {
|
||||||
{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } },
|
6301: [
|
||||||
{ s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
|
{ lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } },
|
||||||
],
|
{ lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } },
|
||||||
2: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] },
|
{ lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } },
|
||||||
3: { hp_bonus: 150 },
|
{ lv: 6, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 2 } },
|
||||||
4: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] },
|
],
|
||||||
5: { atked: [{ s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } }] },
|
6402: [
|
||||||
6: {
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
|
||||||
atked: [
|
],
|
||||||
{ s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } },
|
|
||||||
{ s_uuid: 6402, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
|
|
||||||
{ s_uuid: 6301, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 2 } },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 150 }],
|
||||||
info: "<color=#27AE60>✧</color>受伤获得护盾与生命\n<color=#9B59B6>✦</color>受伤全队获得护盾",
|
info: "<color=#27AE60>✧</color>受伤获得护盾与生命\n<color=#9B59B6>✦</color>受伤全队获得护盾",
|
||||||
},
|
},
|
||||||
5014: {
|
5014: {
|
||||||
uuid: 5014, name: "怒火武者", path: "hk5", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
uuid: 5014, name: "怒火武者", path: "hk5", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } },
|
||||||
atked: [
|
atked: {
|
||||||
{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
6401: [
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
],
|
{ lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
evolve: {
|
],
|
||||||
2: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }] },
|
6403: [
|
||||||
3: { hp_bonus: 150 },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
4: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
|
||||||
5: { atked: [{ s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
6: {
|
],
|
||||||
atked: [
|
6404: [
|
||||||
{ s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
],
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 150 }],
|
||||||
info: "<color=#27AE60>✧</color>受伤提升攻击与暴击\n<color=#9B59B6>✦</color>受伤限时提升暴伤",
|
info: "<color=#27AE60>✧</color>受伤提升攻击与暴击\n<color=#9B59B6>✦</color>受伤限时提升暴伤",
|
||||||
},
|
},
|
||||||
5015: {
|
5015: {
|
||||||
uuid: 5015, name: "血刃武者", path: "hc3", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
uuid: 5015, name: "血刃武者", path: "hc3", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
atked: [
|
atked: {
|
||||||
{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } },
|
6301: [
|
||||||
{ s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } },
|
||||||
],
|
{ lv: 2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } },
|
||||||
2: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } }, { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } }] },
|
{ lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } },
|
||||||
3: { hp_bonus: 200 },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 2 } },
|
||||||
4: { atked: [{ s_uuid: 6301, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] },
|
],
|
||||||
5: { atked: [{ s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } }, { s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] },
|
6404: [
|
||||||
6: {
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
atked: [
|
{ lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } },
|
||||||
{ s_uuid: 6301, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } },
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
|
||||||
{ s_uuid: 6404, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
|
],
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
6403: [
|
||||||
{ s_uuid: 6301, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 2 } },
|
{ lv: 6, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
]
|
],
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 200 }],
|
||||||
info: "<color=#27AE60>✧</color>受伤获得护盾与暴伤\n<color=#9B59B6>✦</color>受伤追加暴击并给全队护盾",
|
info: "<color=#27AE60>✧</color>受伤获得护盾与暴伤\n<color=#9B59B6>✦</color>受伤追加暴击并给全队护盾",
|
||||||
},
|
},
|
||||||
5016: {
|
5016: {
|
||||||
uuid: 5016, name: "狂血战士", path: "hc4", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142,
|
uuid: 5016, name: "狂血战士", path: "hc4", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
atked: [
|
atked: {
|
||||||
{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
6401: [
|
||||||
{ s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
],
|
{ lv: 5, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
evolve: {
|
],
|
||||||
2: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } }] },
|
6405: [
|
||||||
3: { ap_bonus: 20, hp_bonus: 150 },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
|
||||||
4: { atked: [{ s_uuid: 6401, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } },
|
||||||
5: { atked: [{ s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } },
|
||||||
6: {
|
],
|
||||||
atked: [
|
6403: [
|
||||||
{ s_uuid: 6401, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
{ s_uuid: 6405, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } },
|
],
|
||||||
{ s_uuid: 6403, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
6404: [
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
]
|
],
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
ap_bonus: [{ lv: 3, value: 20 }],
|
||||||
|
hp_bonus: [{ lv: 3, value: 150 }],
|
||||||
info: "<color=#27AE60>✧</color>受伤提升攻击与击晕\n<color=#9B59B6>✦</color>受伤追加暴击与暴伤",
|
info: "<color=#27AE60>✧</color>受伤提升攻击与击晕\n<color=#9B59B6>✦</color>受伤追加暴击与暴伤",
|
||||||
},
|
},
|
||||||
// 以下英雄暂时注释,保留待后续扩展
|
// 以下英雄暂时注释,保留待后续扩展
|
||||||
@@ -389,81 +402,62 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5021: {
|
5021: {
|
||||||
uuid: 5021, name: "小刺客", path: "hc1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
uuid: 5021, name: "小刺客", path: "hc1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
|
||||||
atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }],
|
|
||||||
// 成长主线:滚雪球(AP增量固定1,5级阈值5→4刀);6级追加暴伤强化(永久叠加无100%上限,与高AP叠乘)
|
// 成长主线:滚雪球(AP增量固定1,5级阈值5→4刀);6级追加暴伤强化(永久叠加无100%上限,与高AP叠乘)
|
||||||
// 注意:evolve.atking 为整体替换且逐级顺序应用,高级别需写完整数组
|
atking: {
|
||||||
evolve: {
|
6401: [
|
||||||
2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }] },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
3: { ap_bonus: 20, hp_bonus: 80 },
|
{ lv: 5, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }] },
|
],
|
||||||
5: { atking: [{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }] },
|
6404: [
|
||||||
6: {
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 20, buff_duration: 5 } },
|
||||||
atking: [
|
],
|
||||||
{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 20, buff_duration: 5 } },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
ap_bonus: [{ lv: 3, value: 20 }],
|
||||||
|
hp_bonus: [{ lv: 3, value: 80 }],
|
||||||
info: "<color=#27AE60>✧</color>攻击永久提升攻击\n<color=#9B59B6>✦</color>攻击限时提升暴伤",
|
info: "<color=#27AE60>✧</color>攻击永久提升攻击\n<color=#9B59B6>✦</color>攻击限时提升暴伤",
|
||||||
},
|
},
|
||||||
5022: {
|
5022: {
|
||||||
uuid: 5022, name: "嗜血剑客", path: "hc2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
uuid: 5022, name: "嗜血剑客", path: "hc2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
|
||||||
atking: [
|
atking: {
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
6403: [
|
||||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } }
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
],
|
{ lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
2: {
|
{ lv: 5, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
atking: [
|
],
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
|
6401: [
|
||||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } }
|
{ lv: 1, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
]
|
],
|
||||||
},
|
6404: [
|
||||||
3: { ap_bonus: 20, hp_bonus: 80 },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
4: {
|
],
|
||||||
atking: [
|
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
|
||||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
5: {
|
|
||||||
atking: [
|
|
||||||
{ s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
|
||||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
6: {
|
|
||||||
atking: [
|
|
||||||
{ s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
|
||||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
ap_bonus: [{ lv: 3, value: 20 }],
|
||||||
|
hp_bonus: [{ lv: 3, value: 80 }],
|
||||||
info: "<color=#27AE60>✧</color>攻击限时提升暴击\n<color=#9B59B6>✦</color>攻击限时提升暴伤",
|
info: "<color=#27AE60>✧</color>攻击限时提升暴击\n<color=#9B59B6>✦</color>攻击限时提升暴伤",
|
||||||
},
|
},
|
||||||
5023: {
|
5023: {
|
||||||
uuid: 5023, name: "暗影杀手", path: "hc5", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
uuid: 5023, name: "暗影杀手", path: "hc5", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast1].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast1].cd, ccd: 0 } },
|
||||||
atking: [
|
atking: {
|
||||||
{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
6401: [
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
],
|
{ lv: 5, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
||||||
evolve: {
|
],
|
||||||
2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }] },
|
6403: [
|
||||||
3: { hp_bonus: 100 },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
|
||||||
5: { atking: [{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } }, { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
6: {
|
],
|
||||||
atking: [
|
6404: [
|
||||||
{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
],
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
6409: [
|
||||||
{ s_uuid: 6409, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7016, buff_value: 5, buff_duration: 5 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Self, timed_buff_id: 7016, buff_value: 5, buff_duration: 5 } },
|
||||||
]
|
],
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 100 }],
|
||||||
info: "<color=#27AE60>✧</color>攻击提升攻击与暴击\n<color=#9B59B6>✦</color>攻击追加暴伤与风怒",
|
info: "<color=#27AE60>✧</color>攻击提升攻击与暴击\n<color=#9B59B6>✦</color>攻击追加暴伤与风怒",
|
||||||
},
|
},
|
||||||
// 5022: {
|
// 5022: {
|
||||||
@@ -489,38 +483,36 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5031: {
|
5031: {
|
||||||
uuid: 5031, name: "援护弓手", path: "ha1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
uuid: 5031, name: "援护弓手", path: "ha1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } },
|
||||||
atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } }],
|
|
||||||
// 成长主线:AP增益固定1,5级 hit_count 1→2(2英雄环境=全队);6级追加全队攻速光环
|
// 成长主线:AP增益固定1,5级 hit_count 1→2(2英雄环境=全队);6级追加全队攻速光环
|
||||||
// 注意:evolve.atking 为整体替换且逐级顺序应用,高级别需写完整数组;field 为驻场光环覆盖
|
atking: {
|
||||||
evolve: {
|
6401: [
|
||||||
2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } }] },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } },
|
||||||
3: { hp_bonus: 60 },
|
{ lv: 5, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 1 } },
|
||||||
4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } }] },
|
],
|
||||||
5: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 1 } }] },
|
|
||||||
6: { field: [7006] },
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 60 }],
|
||||||
|
field: [{ lv: 6, uuids: [7006] }],
|
||||||
info: "<color=#27AE60>✧</color>攻击提升队友攻击\n<color=#9B59B6>✦</color>光环全队提升攻速",
|
info: "<color=#27AE60>✧</color>攻击提升队友攻击\n<color=#9B59B6>✦</color>光环全队提升攻速",
|
||||||
},
|
},
|
||||||
5032: {
|
5032: {
|
||||||
uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||||
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
|
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
|
||||||
atking: [
|
atking: {
|
||||||
{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
6403: [
|
||||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
],
|
{ lv: 2, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
2: { atking: [{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }] },
|
{ lv: 5, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
3: { hp_bonus: 80 },
|
],
|
||||||
4: { atking: [{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }] },
|
6401: [
|
||||||
5: { atking: [{ s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }] },
|
{ lv: 1, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } },
|
||||||
6: {
|
{ lv: 4, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
|
||||||
atking: [
|
],
|
||||||
{ s_uuid: 6403, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
6404: [
|
||||||
{ s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
],
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 80 }],
|
||||||
info: "<color=#27AE60>✧</color>攻击限时提升队友暴击\n<color=#9B59B6>✦</color>攻击限时提升队友暴伤",
|
info: "<color=#27AE60>✧</color>攻击限时提升队友暴击\n<color=#9B59B6>✦</color>攻击限时提升队友暴伤",
|
||||||
},
|
},
|
||||||
// 5032: {
|
// 5032: {
|
||||||
@@ -532,24 +524,25 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5033: {
|
5033: {
|
||||||
uuid: 5033, name: "鹰眼弓将", path: "ha3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
uuid: 5033, name: "鹰眼弓将", path: "ha3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
|
||||||
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } },
|
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } },
|
||||||
atking: [
|
atking: {
|
||||||
{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } },
|
6401: [
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } },
|
||||||
],
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
|
||||||
evolve: {
|
{ lv: 5, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
|
||||||
2: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } }, { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } }] },
|
],
|
||||||
3: { hp_bonus: 100 },
|
6404: [
|
||||||
4: { atking: [{ s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 1, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
5: { atking: [{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } }, { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 2, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } },
|
||||||
6: {
|
{ lv: 4, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
|
||||||
atking: [
|
],
|
||||||
{ s_uuid: 6401, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
|
6403: [
|
||||||
{ s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
{ s_uuid: 6403, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
],
|
||||||
{ s_uuid: 6405, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
|
6405: [
|
||||||
]
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 100 }],
|
||||||
info: "<color=#27AE60>✧</color>攻击提升队友攻击与暴伤\n<color=#9B59B6>✦</color>攻击追加队友暴击与击晕",
|
info: "<color=#27AE60>✧</color>攻击提升队友攻击与暴伤\n<color=#9B59B6>✦</color>攻击追加队友暴击与击晕",
|
||||||
},
|
},
|
||||||
// 5033: {
|
// 5033: {
|
||||||
@@ -608,83 +601,87 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5041: {
|
5041: {
|
||||||
uuid: 5041, name: "殉道卫士", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
uuid: 5041, name: "殉道卫士", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, hp: 300, ap: 28,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }],
|
dead: {
|
||||||
evolve: {
|
6301: [
|
||||||
2: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } }] },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
||||||
3: { hp_bonus: 100 },
|
{ lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } },
|
||||||
4: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }] },
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
5: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }] },
|
{ lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
|
||||||
6: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }] },
|
],
|
||||||
|
6401: [
|
||||||
|
{ lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 100 }],
|
||||||
info: "<color=#27AE60>✧</color>死亡全队获得护盾\n<color=#9B59B6>✦</color>死亡全队提升攻击",
|
info: "<color=#27AE60>✧</color>死亡全队获得护盾\n<color=#9B59B6>✦</color>死亡全队提升攻击",
|
||||||
},
|
},
|
||||||
5042: {
|
5042: {
|
||||||
uuid: 5042, name: "遗志将军", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
uuid: 5042, name: "遗志将军", path: "hk2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, hp: 600, ap: 57,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
dead: [
|
dead: {
|
||||||
{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
6401: [
|
||||||
{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
],
|
],
|
||||||
revive: { s_uuid: 6501, r_num: 1, upr: 0.5 },
|
6402: [
|
||||||
evolve: {
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
|
||||||
2: { dead: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } }] },
|
{ lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
|
||||||
3: { revive: { s_uuid: 6501, r_num: 1, upr: 0.6 } },
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
|
||||||
4: { dead: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }] },
|
],
|
||||||
5: { revive: { s_uuid: 6501, r_num: 1, upr: 0.7 } },
|
6301: [
|
||||||
6: {
|
{ lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
||||||
dead: [
|
],
|
||||||
{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
|
||||||
{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
|
|
||||||
{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
|
||||||
],
|
|
||||||
revive: { s_uuid: 6501, r_num: 1, upr: 0.8 },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
revive: [
|
||||||
|
{ lv: 1, s_uuid: 6501, r_num: 1, upr: 0.5 },
|
||||||
|
{ lv: 3, s_uuid: 6501, r_num: 1, upr: 0.6 },
|
||||||
|
{ lv: 5, s_uuid: 6501, r_num: 1, upr: 0.7 },
|
||||||
|
{ lv: 6, s_uuid: 6501, r_num: 1, upr: 0.8 },
|
||||||
|
],
|
||||||
info: "<color=#27AE60>✧</color>死亡全队攻血提升\n<color=#9B59B6>✦</color>死亡全队护盾并复活",
|
info: "<color=#27AE60>✧</color>死亡全队攻血提升\n<color=#9B59B6>✦</color>死亡全队护盾并复活",
|
||||||
},
|
},
|
||||||
5043: {
|
5043: {
|
||||||
uuid: 5043, name: "亡魂刺客", path: "hc1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
uuid: 5043, name: "亡魂刺客", path: "hc1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, hp: 900, ap: 85,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
|
||||||
dead: [
|
dead: {
|
||||||
{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
|
6405: [
|
||||||
{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
|
||||||
],
|
{ lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } },
|
||||||
2: { dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } }, { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } }] },
|
],
|
||||||
3: { hp_bonus: 100 },
|
6403: [
|
||||||
4: { dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 6 } }] },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
5: { dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 6 } },
|
||||||
6: {
|
{ lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
dead: [
|
],
|
||||||
{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } },
|
6401: [
|
||||||
{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
{ lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
],
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 100 }],
|
||||||
info: "<color=#27AE60>✧</color>死亡全队击晕与暴击\n<color=#9B59B6>✦</color>死亡全队提升攻击",
|
info: "<color=#27AE60>✧</color>死亡全队击晕与暴击\n<color=#9B59B6>✦</color>死亡全队提升攻击",
|
||||||
},
|
},
|
||||||
5044: {
|
5044: {
|
||||||
uuid: 5044, name: "血誓剑客", path: "hc2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
uuid: 5044, name: "血誓剑客", path: "hc2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, hp: 1200, ap: 113,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } },
|
||||||
dead: [
|
dead: {
|
||||||
{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
6403: [
|
||||||
{ s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
],
|
{ lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
||||||
2: { dead: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } }, { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } }] },
|
],
|
||||||
3: { hp_bonus: 150 },
|
6404: [
|
||||||
4: { dead: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 7, buff_duration: 6 } }] },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
|
||||||
5: { dead: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } }, { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } }] },
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 7, buff_duration: 6 } },
|
||||||
6: {
|
{ lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
|
||||||
dead: [
|
],
|
||||||
{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
|
6401: [
|
||||||
{ s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
|
{ lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
],
|
||||||
{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
|
6402: [
|
||||||
]
|
{ lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
|
||||||
},
|
],
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 150 }],
|
||||||
info: "<color=#27AE60>✧</color>死亡全队暴击与暴伤\n<color=#9B59B6>✦</color>死亡全队攻击与生命",
|
info: "<color=#27AE60>✧</color>死亡全队暴击与暴伤\n<color=#9B59B6>✦</color>死亡全队攻击与生命",
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -694,25 +691,31 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5045: {
|
5045: {
|
||||||
uuid: 5045, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 60,
|
uuid: 5045, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 60,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
|
||||||
// 死亡释放:5 层护盾 + 全队 +10 HP;复活 1 次血量 50%
|
// 死亡释放:5 层护盾 + 全队 +10 HP;复活 1 次血量 50%。6级终极遗志追加 AP+5 / 暴击 5%,复活 2 次 70%
|
||||||
dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }],
|
dead: {
|
||||||
revive: { s_uuid: 6501, r_num: 1, upr: 0.5 },
|
6301: [
|
||||||
evolve: {
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
2: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } }] },
|
{ lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
|
||||||
3: { revive: { s_uuid: 6501, r_num: 1, upr: 0.6 } },
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } },
|
||||||
4: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }] },
|
{ lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } },
|
||||||
5: { dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }] },
|
],
|
||||||
// 6级终极遗志:追加 AP+5 + 暴击计时 5%;终极涅槃:复活 2 次血量 70%
|
6402: [
|
||||||
6: {
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
|
||||||
dead: [
|
{ lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
|
||||||
{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } },
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
|
||||||
{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
|
],
|
||||||
{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
6401: [
|
||||||
{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
{ lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
],
|
],
|
||||||
revive: { s_uuid: 6501, r_num: 2, upr: 0.7 },
|
6403: [
|
||||||
},
|
{ lv: 6, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
|
revive: [
|
||||||
|
{ lv: 1, s_uuid: 6501, r_num: 1, upr: 0.5 },
|
||||||
|
{ lv: 3, s_uuid: 6501, r_num: 1, upr: 0.6 },
|
||||||
|
{ lv: 6, s_uuid: 6501, r_num: 2, upr: 0.7 },
|
||||||
|
],
|
||||||
info: "<color=#27AE60>✧</color>死亡全队加护盾\n<color=#27AE60>✧</color>复活1:50%血量\n<color=#9B59B6>✦</color>死亡加攻击\n<color=#9B59B6>✦</color>复活2:70%血量",
|
info: "<color=#27AE60>✧</color>死亡全队加护盾\n<color=#27AE60>✧</color>复活1:50%血量\n<color=#9B59B6>✦</color>死亡加攻击\n<color=#9B59B6>✦</color>复活2:70%血量",
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -722,30 +725,33 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
|
||||||
// 战前计时 buff:每波开始全队 AP 限时提升(+30/5s → +60/7s → +90/10s),6级追加暴击驻场光环
|
// 战前计时 buff:每波开始全队 AP 限时提升(+30/5s → +60/7s → +90/10s),6级追加暴击驻场光环
|
||||||
// 统一复用 7111 基础配置,通过 buff_value/buff_duration 覆写实现三档成长
|
// 统一复用 7111 基础配置,通过 buff_value/buff_duration 覆写实现三档成长
|
||||||
fstart: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111 } }],
|
fstart: {
|
||||||
evolve: {
|
6401: [
|
||||||
2: { hp_bonus: 80 },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111 } },
|
||||||
3: { fstart: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 60, buff_duration: 7 } }] },
|
{ lv: 3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 60, buff_duration: 7 } },
|
||||||
4: { hp_bonus: 80 },
|
{ lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 90, buff_duration: 10 } },
|
||||||
5: { fstart: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 90, buff_duration: 10 } }] },
|
],
|
||||||
6: { field: [7204] },
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 2, value: 80 }, { lv: 4, value: 80 }],
|
||||||
|
field: [{ lv: 6, uuids: [7204] }],
|
||||||
info: "<color=#27AE60>✧</color>开局全队提升攻击\n<color=#9B59B6>✦</color>光环全队提升暴击",
|
info: "<color=#27AE60>✧</color>开局全队提升攻击\n<color=#9B59B6>✦</color>光环全队提升暴击",
|
||||||
},
|
},
|
||||||
5052: {
|
5052: {
|
||||||
uuid: 5052, name: "护盾牧师", path: "hm2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
uuid: 5052, name: "护盾牧师", path: "hm2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } },
|
||||||
fstart: [
|
fstart: {
|
||||||
{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
6301: [
|
||||||
{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
||||||
],
|
{ lv: 2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } },
|
||||||
evolve: {
|
{ lv: 4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
|
||||||
2: { fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }] },
|
{ lv: 5, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
|
||||||
3: { hp_bonus: 80 },
|
],
|
||||||
4: { fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }] },
|
6402: [
|
||||||
5: { fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } }, { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }] },
|
{ lv: 1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } },
|
||||||
6: { field: [7007] },
|
],
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 80 }],
|
||||||
|
field: [{ lv: 6, uuids: [7007] }],
|
||||||
info: "<color=#27AE60>✧</color>开局全队获得护盾\n<color=#9B59B6>✦</color>光环全队提升生命",
|
info: "<color=#27AE60>✧</color>开局全队获得护盾\n<color=#9B59B6>✦</color>光环全队提升生命",
|
||||||
},
|
},
|
||||||
// 5052: {
|
// 5052: {
|
||||||
@@ -796,14 +802,13 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5061: {
|
5061: {
|
||||||
uuid: 5061, name: "战歌法师", path: "hm3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
uuid: 5061, name: "战歌法师", path: "hm3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
|
||||||
field: [7002, 7006],
|
field: [
|
||||||
evolve: {
|
{ lv: 1, uuids: [7002, 7006] },
|
||||||
2: { field: [7202, 7006] },
|
{ lv: 2, uuids: [7202, 7006] },
|
||||||
3: { hp_bonus: 80 },
|
{ lv: 4, uuids: [7202, 7206] },
|
||||||
4: { field: [7202, 7206] },
|
{ lv: 6, uuids: [7202, 7206, 7007] },
|
||||||
5: { field: [7202, 7206] },
|
],
|
||||||
6: { field: [7202, 7206, 7007] },
|
hp_bonus: [{ lv: 3, value: 80 }],
|
||||||
},
|
|
||||||
info: "<color=#27AE60>✧</color>光环全队提升攻击\n<color=#9B59B6>✦</color>追加提升攻速生命",
|
info: "<color=#27AE60>✧</color>光环全队提升攻击\n<color=#9B59B6>✦</color>追加提升攻速生命",
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -811,21 +816,19 @@ export const HeroInfo: Record<number, heroInfo> = {
|
|||||||
5071: {
|
5071: {
|
||||||
uuid: 5071, name: "治愈牧师", path: "hh1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
uuid: 5071, name: "治愈牧师", path: "hh1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
|
||||||
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
|
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
|
||||||
atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } }],
|
|
||||||
// 成长主线:治疗量 200→250→300%,5级 hit_count 1→2(全队);6级追加护盾 atking,攻防一体
|
// 成长主线:治疗量 200→250→300%,5级 hit_count 1→2(全队);6级追加护盾 atking,攻防一体
|
||||||
// 注意:evolve.atking 为整体替换且逐级顺序应用,高级别需写完整数组
|
atking: {
|
||||||
evolve: {
|
6302: [
|
||||||
2: { atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } }] },
|
{ lv: 1, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } },
|
||||||
3: { hp_bonus: 80 },
|
{ lv: 2, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } },
|
||||||
4: { atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 300 } }] },
|
{ lv: 4, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 300 } },
|
||||||
5: { atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 300 } }] },
|
{ lv: 5, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 300 } },
|
||||||
6: {
|
],
|
||||||
atking: [
|
6301: [
|
||||||
{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 300 } },
|
{ lv: 6, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
||||||
{ s_uuid: 6301, t_num: 7, overrides: { TGroup: TGroup.Team, ap: 3 } },
|
],
|
||||||
]
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
hp_bonus: [{ lv: 3, value: 80 }],
|
||||||
info: "<color=#27AE60>✧</color>攻击治疗低血队友\n<color=#9B59B6>✦</color>攻击全队获得护盾",
|
info: "<color=#27AE60>✧</color>攻击治疗低血队友\n<color=#9B59B6>✦</color>攻击全队获得护盾",
|
||||||
},
|
},
|
||||||
// 5072: {
|
// 5072: {
|
||||||
@@ -995,23 +998,64 @@ export const HERO_POWER_WEIGHTS = {
|
|||||||
DEFAULT_EVAL_SECONDS: 60,
|
DEFAULT_EVAL_SECONDS: 60,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 计算目标等级下 evolve 提供的累计属性加成 */
|
/**
|
||||||
|
* 解析触发技能在目标等级下的有效条目列表。
|
||||||
|
* 每个 s_uuid 取 ≤lv 的最大档;返回扁平数组供评分/触发器消费。
|
||||||
|
*/
|
||||||
|
export function resolveTriggerByLv(grouped: TriggerGrouped | undefined, lv: number): { s_uuid: number; t_num: number; overrides?: SkillOverrides }[] {
|
||||||
|
if (!grouped) return [];
|
||||||
|
const result: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[] = [];
|
||||||
|
for (const key in grouped) {
|
||||||
|
const entries = grouped[key];
|
||||||
|
if (!entries || entries.length === 0) continue;
|
||||||
|
let pick: LvTriggerEntry | undefined;
|
||||||
|
for (const e of entries) {
|
||||||
|
if (e.lv <= lv && (!pick || e.lv > pick.lv)) pick = e;
|
||||||
|
}
|
||||||
|
if (pick) result.push({ s_uuid: Number(key), t_num: pick.t_num, overrides: pick.overrides });
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 解析驻场光环在目标等级下的有效 uuid 列表(取 ≤lv 的最大档) */
|
||||||
|
export function resolveFieldByLv(field: LvFieldEntry[] | undefined, lv: number): number[] {
|
||||||
|
if (!field || field.length === 0) return [];
|
||||||
|
let pick: LvFieldEntry | undefined;
|
||||||
|
for (const e of field) {
|
||||||
|
if (e.lv <= lv && (!pick || e.lv > pick.lv)) pick = e;
|
||||||
|
}
|
||||||
|
return pick ? pick.uuids : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 解析复活技能在目标等级下的有效配置(取 ≤lv 的最大档) */
|
||||||
|
export function resolveReviveByLv(revive: LvReviveEntry[] | undefined, lv: number): { s_uuid: number; r_num: number; upr: number } | undefined {
|
||||||
|
if (!revive || revive.length === 0) return undefined;
|
||||||
|
let pick: LvReviveEntry | undefined;
|
||||||
|
for (const e of revive) {
|
||||||
|
if (e.lv <= lv && (!pick || e.lv > pick.lv)) pick = e;
|
||||||
|
}
|
||||||
|
return pick ? { s_uuid: pick.s_uuid, r_num: pick.r_num, upr: pick.upr } : undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 计算目标等级下额外属性加成(hp_bonus/ap_bonus 按 lv 累加) */
|
||||||
function getEvolveBonuses(hero: heroInfo, targetLv: number): { hp: number, ap: number } {
|
function getEvolveBonuses(hero: heroInfo, targetLv: number): { hp: number, ap: number } {
|
||||||
let hp = 0;
|
let hp = 0;
|
||||||
let ap = 0;
|
let ap = 0;
|
||||||
if (!hero.evolve) return { hp, ap };
|
const lv = Math.max(1, targetLv);
|
||||||
const maxLv = Math.max(1, Math.min(targetLv, FightSet.HERO_MAX_LV));
|
if (hero.hp_bonus) {
|
||||||
for (let lv = 2; lv <= maxLv; lv++) {
|
for (const e of hero.hp_bonus) {
|
||||||
const ev = hero.evolve[lv];
|
if (e.lv <= lv) hp += e.value;
|
||||||
if (ev) {
|
}
|
||||||
hp += ev.hp_bonus || 0;
|
}
|
||||||
ap += ev.ap_bonus || 0;
|
if (hero.ap_bonus) {
|
||||||
|
for (const e of hero.ap_bonus) {
|
||||||
|
if (e.lv <= lv) ap += e.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { hp, ap };
|
return { hp, ap };
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 计算目标等级下的有效 HP/AP(含等级倍率与 evolve 加成) */
|
/** 计算目标等级下的有效 HP/AP(含等级倍率与额外加成) */
|
||||||
function getEffectiveStats(hero: heroInfo, targetLv: number): { hp: number, ap: number } {
|
function getEffectiveStats(hero: heroInfo, targetLv: number): { hp: number, ap: number } {
|
||||||
const bonuses = getEvolveBonuses(hero, targetLv);
|
const bonuses = getEvolveBonuses(hero, targetLv);
|
||||||
const lv = Math.max(1, targetLv);
|
const lv = Math.max(1, targetLv);
|
||||||
@@ -1068,7 +1112,7 @@ function getTriggerCount(
|
|||||||
case SkillTriggerType.FEnd:
|
case SkillTriggerType.FEnd:
|
||||||
return getWaveCount(seconds);
|
return getWaveCount(seconds);
|
||||||
case SkillTriggerType.Dead:
|
case SkillTriggerType.Dead:
|
||||||
return getWaveCount(seconds) * (1 + (hero.revive?.r_num || 0));
|
return getWaveCount(seconds) * (1 + (resolveReviveByLv(hero.revive, FightSet.HERO_MAX_LV)?.r_num || 0));
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -1338,16 +1382,18 @@ export function calcHeroPowerDetailed(hero: heroInfo, targetLv: number = 1, seco
|
|||||||
const dpsValue = (apEff / cd) * weights.W_DPS_PER_SEC * seconds;
|
const dpsValue = (apEff / cd) * weights.W_DPS_PER_SEC * seconds;
|
||||||
const normalAttack = getNormalAttackInfo(hero, targetLv, seconds);
|
const normalAttack = getNormalAttackInfo(hero, targetLv, seconds);
|
||||||
|
|
||||||
const atking = hero.atking ? calcTriggerPowerDetailed(hero.atking, hero, targetLv, SkillTriggerType.Atking, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const atking = hero.atking ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atking, targetLv), hero, targetLv, SkillTriggerType.Atking, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const atked = hero.atked ? calcTriggerPowerDetailed(hero.atked, hero, targetLv, SkillTriggerType.Atked, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const atked = hero.atked ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atked, targetLv), hero, targetLv, SkillTriggerType.Atked, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const fstart = hero.fstart ? calcTriggerPowerDetailed(hero.fstart, hero, targetLv, SkillTriggerType.FStart, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const fstart = hero.fstart ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.fstart, targetLv), hero, targetLv, SkillTriggerType.FStart, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const fend = hero.fend ? calcTriggerPowerDetailed(hero.fend, hero, targetLv, SkillTriggerType.FEnd, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const fend = hero.fend ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.fend, targetLv), hero, targetLv, SkillTriggerType.FEnd, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const dead = hero.dead ? calcTriggerPowerDetailed(hero.dead, hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
const dead = hero.dead ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.dead, targetLv), hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
|
||||||
const field = hero.field ? calcFieldPowerDetailed(hero.field, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] };
|
const fieldUuids = resolveFieldByLv(hero.field, targetLv);
|
||||||
|
const field = fieldUuids.length > 0 ? calcFieldPowerDetailed(fieldUuids, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] };
|
||||||
|
|
||||||
let reviveValue = 0;
|
let reviveValue = 0;
|
||||||
if (hero.revive) {
|
const revive = resolveReviveByLv(hero.revive, targetLv);
|
||||||
reviveValue = hpEff * hero.revive.upr * hero.revive.r_num * weights.W_revive * getWaveCount(seconds);
|
if (revive) {
|
||||||
|
reviveValue = hpEff * revive.upr * revive.r_num * weights.W_revive * getWaveCount(seconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
const total = hpValue + dpsValue + atking.total + atked.total + fstart.total + fend.total + dead.total + field.total + reviveValue;
|
const total = hpValue + dpsValue + atking.total + atked.total + fstart.total + fend.total + dead.total + field.total + reviveValue;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { FacSet } from "../common/config/GameSet";
|
import { FacSet } from "../common/config/GameSet";
|
||||||
import { HeroInfo } from "../common/config/heroSet";
|
|
||||||
import { FieldSkillSet, FieldSkillType } from "../common/config/SkillSet";
|
import { FieldSkillSet, FieldSkillType } from "../common/config/SkillSet";
|
||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
import { SkillBoxComp } from "../map/SkillBoxComp";
|
import { SkillBoxComp } from "../map/SkillBoxComp";
|
||||||
@@ -19,12 +18,11 @@ export class FieldSkillHelper {
|
|||||||
let total = 0;
|
let total = 0;
|
||||||
|
|
||||||
// 1. 统计英雄带来的驻场技能加成
|
// 1. 统计英雄带来的驻场技能加成
|
||||||
// 读 model.field(运行时):优先使用 evolve 覆盖后的驻场配置,未升级时回退到 heroInfo 基础配置
|
// 读 model.runtime_field(已按当前等级 resolve 的 uuid 列表)
|
||||||
ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => {
|
ecs.query(ecs.allOf(HeroAttrsComp)).forEach((entity: ecs.Entity) => {
|
||||||
const model = entity.get(HeroAttrsComp);
|
const model = entity.get(HeroAttrsComp);
|
||||||
if (!model || model.is_dead || model.fac !== FacSet.HERO) return;
|
if (!model || model.is_dead || model.fac !== FacSet.HERO) return;
|
||||||
const heroConfig = HeroInfo[model.hero_uuid];
|
const fields = model.runtime_field;
|
||||||
const fields = model.field ?? heroConfig?.field;
|
|
||||||
if (fields) {
|
if (fields) {
|
||||||
for (const skillUuid of fields) {
|
for (const skillUuid of fields) {
|
||||||
const skillConfig = FieldSkillSet[skillUuid];
|
const skillConfig = FieldSkillSet[skillUuid];
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { smc } from "../common/SingletonModuleComp";
|
|||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
import { HeroViewComp } from "./HeroViewComp";
|
import { HeroViewComp } from "./HeroViewComp";
|
||||||
import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet";
|
import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet";
|
||||||
import { HeroInfo, HeroPos, resolveFormationTargetX } from "../common/config/heroSet";
|
import { HeroInfo, HeroPos, resolveFormationTargetX, resolveTriggerByLv, resolveFieldByLv, resolveReviveByLv } from "../common/config/heroSet";
|
||||||
import { GameEvent } from "../common/config/GameEvent";
|
import { GameEvent } from "../common/config/GameEvent";
|
||||||
import { SkillTriggerType } from "../common/config/heroSet";
|
import { SkillTriggerType } from "../common/config/heroSet";
|
||||||
import { SkillTriggerHelper } from "./SkillTriggerHelper";
|
import { SkillTriggerHelper } from "./SkillTriggerHelper";
|
||||||
@@ -126,7 +126,7 @@ export class Hero extends ecs.Entity {
|
|||||||
smc.mission.heroGrid[posIndex] = this.eid;
|
smc.mission.heroGrid[posIndex] = this.eid;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 复制触发技能配置
|
// 复制触发技能配置(新结构:按 s_uuid 分组 + lv 数组)
|
||||||
model.call = hero.call;
|
model.call = hero.call;
|
||||||
model.dead = hero.dead;
|
model.dead = hero.dead;
|
||||||
model.fstart = hero.fstart;
|
model.fstart = hero.fstart;
|
||||||
@@ -135,6 +135,8 @@ export class Hero extends ecs.Entity {
|
|||||||
model.atked = hero.atked;
|
model.atked = hero.atked;
|
||||||
model.field = hero.field;
|
model.field = hero.field;
|
||||||
model.revive = hero.revive;
|
model.revive = hero.revive;
|
||||||
|
model.ap_bonus = hero.ap_bonus;
|
||||||
|
model.hp_bonus = hero.hp_bonus;
|
||||||
|
|
||||||
// 基础属性按等级倍率初始化
|
// 基础属性按等级倍率初始化
|
||||||
// 使用指数增长公式:等级 2 时为原来的 HERO_LV_MULTIPLIER 倍,等级 3 时为 HERO_LV_MULTIPLIER^2 倍
|
// 使用指数增长公式:等级 2 时为原来的 HERO_LV_MULTIPLIER 倍,等级 3 时为 HERO_LV_MULTIPLIER^2 倍
|
||||||
@@ -164,38 +166,26 @@ export class Hero extends ecs.Entity {
|
|||||||
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + hero_lv - 2), ccd: 0 };
|
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + hero_lv - 2), ccd: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用等级进化配置(从 lv2 开始逐级覆盖)
|
// 按当前英雄等级 resolve 触发技能/光环/复活到运行时缓存,供 SkillTriggerHelper 消费
|
||||||
if (hero.evolve) {
|
model.runtime_call = resolveTriggerByLv(model.call, hero_lv);
|
||||||
// 记录 evolve 配置快照(只读引用),供 UI 计算 ap/hp 额外加成文案
|
model.runtime_dead = resolveTriggerByLv(model.dead, hero_lv);
|
||||||
model.evolve = hero.evolve;
|
model.runtime_fstart = resolveTriggerByLv(model.fstart, hero_lv);
|
||||||
for (let elv = 2; elv <= hero_lv; elv++) {
|
model.runtime_fend = resolveTriggerByLv(model.fend, hero_lv);
|
||||||
const evo = hero.evolve[elv];
|
model.runtime_atking = resolveTriggerByLv(model.atking, hero_lv);
|
||||||
if (!evo) continue;
|
model.runtime_atked = resolveTriggerByLv(model.atked, hero_lv);
|
||||||
// 替换普攻技能
|
model.runtime_field = resolveFieldByLv(model.field, hero_lv);
|
||||||
if (evo.skill) {
|
model.runtime_revive = resolveReviveByLv(model.revive, hero_lv);
|
||||||
const oldSkill = Object.values(model.skills)[0];
|
|
||||||
model.skills = {};
|
// 应用额外属性加成(hp_bonus/ap_bonus 按 ≤英雄等级 累加)
|
||||||
model.skills[evo.skill.s_uuid] = {
|
if (model.hp_bonus) {
|
||||||
uuid: evo.skill.s_uuid,
|
let hpExtra = 0;
|
||||||
lv: Math.max(0, 1 + hero_lv - 2),
|
for (const e of model.hp_bonus) { if (e.lv <= hero_lv) hpExtra += e.value; }
|
||||||
cd: evo.skill.cd ?? oldSkill?.cd ?? 1,
|
model.hp += hpExtra; model.hp_max += hpExtra;
|
||||||
ccd: 0,
|
}
|
||||||
overrides: evo.skill.overrides,
|
if (model.ap_bonus) {
|
||||||
};
|
let apExtra = 0;
|
||||||
}
|
for (const e of model.ap_bonus) { if (e.lv <= hero_lv) apExtra += e.value; }
|
||||||
// 覆盖触发技能
|
model.ap += apExtra;
|
||||||
if (evo.atking) model.atking = evo.atking;
|
|
||||||
if (evo.atked) model.atked = evo.atked;
|
|
||||||
if (evo.dead) model.dead = evo.dead;
|
|
||||||
if (evo.fstart) model.fstart = evo.fstart;
|
|
||||||
if (evo.fend) model.fend = evo.fend;
|
|
||||||
// 覆盖驻场光环(存活期间全局生效)
|
|
||||||
if (evo.field) model.field = evo.field;
|
|
||||||
if (evo.revive) model.revive = evo.revive;
|
|
||||||
// 额外属性加成
|
|
||||||
if (evo.ap_bonus) model.ap += evo.ap_bonus;
|
|
||||||
if (evo.hp_bonus) { model.hp += evo.hp_bonus; model.hp_max += evo.hp_bonus; }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 缓存技能射程等派生数据,减少战斗帧内重复计算
|
// 缓存技能射程等派生数据,减少战斗帧内重复计算
|
||||||
|
|||||||
@@ -228,8 +228,8 @@ export class HeroAtkSystem extends ecs.ComblockSystem implements ecs.ISystemUpda
|
|||||||
let maxReviveCount = 0;
|
let maxReviveCount = 0;
|
||||||
let reviveHpPercent = 50; // 默认恢复50%
|
let reviveHpPercent = 50; // 默认恢复50%
|
||||||
let reviveSkillConf: any = null; // 提取出来的复活技能配置
|
let reviveSkillConf: any = null; // 提取出来的复活技能配置
|
||||||
if (TAttrsComp.revive) {
|
if (TAttrsComp.runtime_revive) {
|
||||||
const reviveConf = TAttrsComp.revive;
|
const reviveConf = TAttrsComp.runtime_revive;
|
||||||
maxReviveCount = reviveConf.r_num + Math.floor((TAttrsComp.lv - 1) * reviveConf.upr);
|
maxReviveCount = reviveConf.r_num + Math.floor((TAttrsComp.lv - 1) * reviveConf.upr);
|
||||||
if (TAttrsComp.revived_count < maxReviveCount) {
|
if (TAttrsComp.revived_count < maxReviveCount) {
|
||||||
canRevive = true;
|
canRevive = true;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { HeroDisVal, HeroInfo, HSkillInfo, HType, SkillTriggerType, HeroEvolve } from "../common/config/heroSet";
|
import { HeroDisVal, HeroInfo, HSkillInfo, HType, SkillTriggerType, TriggerGrouped, LvFieldEntry, LvReviveEntry, LvBonusEntry } from "../common/config/heroSet";
|
||||||
import { mLogger } from "../common/Logger";
|
import { mLogger } from "../common/Logger";
|
||||||
import { FacSet, FightSet } from "../common/config/GameSet";
|
import { FacSet, FightSet } from "../common/config/GameSet";
|
||||||
import { FieldSkillSet, FieldSkillType, SkillOverrides } from "../common/config/SkillSet";
|
import { FieldSkillSet, FieldSkillType, SkillOverrides } from "../common/config/SkillSet";
|
||||||
@@ -41,19 +41,37 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
// ==================== 攻击属性 (补充) ====================
|
// ==================== 攻击属性 (补充) ====================
|
||||||
skills: Record<number, HSkillInfo> = {};
|
skills: Record<number, HSkillInfo> = {};
|
||||||
|
|
||||||
// ==================== 触发类技能 ====================
|
// ==================== 触发类技能(静态配置,按 s_uuid 分组 + lv 数组) ====================
|
||||||
[SkillTriggerType.Call]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
[SkillTriggerType.Call]?: TriggerGrouped;
|
||||||
[SkillTriggerType.Dead]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
[SkillTriggerType.Dead]?: TriggerGrouped;
|
||||||
[SkillTriggerType.FStart]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
[SkillTriggerType.FStart]?: TriggerGrouped;
|
||||||
[SkillTriggerType.FEnd]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
[SkillTriggerType.FEnd]?: TriggerGrouped;
|
||||||
[SkillTriggerType.Atking]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
[SkillTriggerType.Atking]?: TriggerGrouped;
|
||||||
[SkillTriggerType.Atked]?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
[SkillTriggerType.Atked]?: TriggerGrouped;
|
||||||
/** 驻场光环(FieldSkillSet uuid 列表,随 evolve 覆盖,存活期间全局生效) */
|
/** 驻场光环(按 lv 解锁,存活期间全局生效) */
|
||||||
[SkillTriggerType.Field]?: number[];
|
[SkillTriggerType.Field]?: LvFieldEntry[];
|
||||||
[SkillTriggerType.Revive]?: { s_uuid: number, r_num: number, upr: number };
|
[SkillTriggerType.Revive]?: LvReviveEntry[];
|
||||||
|
/** 额外攻击/生命加成(按 lv 累加) */
|
||||||
|
ap_bonus?: LvBonusEntry[];
|
||||||
|
hp_bonus?: LvBonusEntry[];
|
||||||
|
|
||||||
/** 等级进化配置快照(引用 heroInfo.evolve,只读;供 UI 计算 ap/hp 额外加成文案) */
|
// ==================== 运行时解析缓存(按当前等级 resolve 后的有效列表) ====================
|
||||||
evolve?: Record<number, HeroEvolve>;
|
/** 当前等级下生效的攻击触发条目(供 SkillTriggerHelper 消费) */
|
||||||
|
runtime_atking?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
|
/** 当前等级下生效的受击触发条目 */
|
||||||
|
runtime_atked?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
|
/** 当前等级下生效的召唤触发条目 */
|
||||||
|
runtime_call?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
|
/** 当前等级下生效的死亡触发条目 */
|
||||||
|
runtime_dead?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
|
/** 当前等级下生效的战前触发条目 */
|
||||||
|
runtime_fstart?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
|
/** 当前等级下生效的战后触发条目 */
|
||||||
|
runtime_fend?: { s_uuid: number; t_num: number; overrides?: SkillOverrides }[];
|
||||||
|
/** 当前等级下生效的驻场光环 uuid 列表 */
|
||||||
|
runtime_field?: number[];
|
||||||
|
/** 当前等级下生效的复活配置 */
|
||||||
|
runtime_revive?: { s_uuid: number; r_num: number; upr: number };
|
||||||
|
|
||||||
// ==================== 特殊属性 ====================
|
// ==================== 特殊属性 ====================
|
||||||
critical: number = 0; // 暴击率
|
critical: number = 0; // 暴击率
|
||||||
@@ -547,8 +565,18 @@ export class HeroAttrsComp extends ecs.Comp {
|
|||||||
this.fend = undefined;
|
this.fend = undefined;
|
||||||
this.atking = undefined;
|
this.atking = undefined;
|
||||||
this.atked = undefined;
|
this.atked = undefined;
|
||||||
|
this.field = undefined;
|
||||||
this.revive = undefined;
|
this.revive = undefined;
|
||||||
this.evolve = undefined;
|
this.ap_bonus = undefined;
|
||||||
|
this.hp_bonus = undefined;
|
||||||
|
this.runtime_atking = undefined;
|
||||||
|
this.runtime_atked = undefined;
|
||||||
|
this.runtime_call = undefined;
|
||||||
|
this.runtime_dead = undefined;
|
||||||
|
this.runtime_fstart = undefined;
|
||||||
|
this.runtime_fend = undefined;
|
||||||
|
this.runtime_field = undefined;
|
||||||
|
this.runtime_revive = undefined;
|
||||||
this.critical = 0;
|
this.critical = 0;
|
||||||
this.critical_res = 0;
|
this.critical_res = 0;
|
||||||
this.freeze_chance = 0;
|
this.freeze_chance = 0;
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 如果角色带有死亡触发技能,则由 SCastSystem 播放 playReady("dead")
|
// 如果角色带有死亡触发技能,则由 SCastSystem 播放 playReady("dead")
|
||||||
if (this.model && this.model.dead && this.model.dead.length > 0) {
|
if (this.model && this.model.runtime_dead && this.model.runtime_dead.length > 0) {
|
||||||
// SCastSystem will handle the "dead" ready animation
|
// SCastSystem will handle the "dead" ready animation
|
||||||
} else {
|
} else {
|
||||||
// 播放默认死亡特效
|
// 播放默认死亡特效
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, NodePool, tween, Tween} from "cc";
|
import { instantiate, Node, Prefab, Vec3, v3, resources, SpriteFrame, Sprite, SpriteAtlas, BoxCollider2D, NodePool, tween, Tween } from "cc";
|
||||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet";
|
import { BoxSet, FacSet, FightSet, IndexSet } from "../common/config/GameSet";
|
||||||
import { HeroInfo } from "../common/config/heroSet";
|
import { HeroInfo, resolveTriggerByLv, resolveReviveByLv } from "../common/config/heroSet";
|
||||||
import { HeroAttrsComp } from "./HeroAttrsComp";
|
import { HeroAttrsComp } from "./HeroAttrsComp";
|
||||||
import { HeroViewComp } from "./HeroViewComp";
|
import { HeroViewComp } from "./HeroViewComp";
|
||||||
import { MoveComp } from "./MoveComp";
|
import { MoveComp } from "./MoveComp";
|
||||||
@@ -109,10 +109,10 @@ export class Monster extends ecs.Entity {
|
|||||||
const model = this.get(HeroAttrsComp);
|
const model = this.get(HeroAttrsComp);
|
||||||
const view = this.get(HeroViewComp);
|
const view = this.get(HeroViewComp);
|
||||||
if (model && view && view.node && view.node.isValid) {
|
if (model && view && view.node && view.node.isValid) {
|
||||||
const path = "game/heros/" + HeroInfo[model.hero_uuid].path;
|
const path = "game/heros/" + HeroInfo[model.hero_uuid].path;
|
||||||
Monster.putToPool(path, view.node);
|
Monster.putToPool(path, view.node);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model && model.posIndex >= 0) {
|
if (model && model.posIndex >= 0) {
|
||||||
if (smc.mission.monGrid[model.posIndex] === this.eid) {
|
if (smc.mission.monGrid[model.posIndex] === this.eid) {
|
||||||
smc.mission.monGrid[model.posIndex] = -1;
|
smc.mission.monGrid[model.posIndex] = -1;
|
||||||
@@ -131,15 +131,15 @@ export class Monster extends ecs.Entity {
|
|||||||
* 2) 初始化表现、属性、技能与阵营
|
* 2) 初始化表现、属性、技能与阵营
|
||||||
* 3) 播放下落入场并在落地后启用碰撞与移动
|
* 3) 播放下落入场并在落地后启用碰撞与移动
|
||||||
*/
|
*/
|
||||||
load(pos: Vec3 = Vec3.ZERO,scale:number = 1,uuid:number=1001, is_boss:boolean=false, dropToY:number = pos.y,mon_lv:number=1, laneIndex:number = 0) {
|
load(pos: Vec3 = Vec3.ZERO, scale: number = 1, uuid: number = 1001, is_boss: boolean = false, dropToY: number = pos.y, mon_lv: number = 1, laneIndex: number = 0) {
|
||||||
// 怪物默认朝左,表现缩放固定为负向
|
// 怪物默认朝左,表现缩放固定为负向
|
||||||
scale=-1
|
scale = -1
|
||||||
// 当前怪物尺寸固定,保留变量便于后续扩展
|
// 当前怪物尺寸固定,保留变量便于后续扩展
|
||||||
let size=1.15
|
let size = 1.15
|
||||||
var scene = smc.map.MapView.scene;
|
var scene = smc.map.MapView.scene;
|
||||||
// 根据配置读取怪物预制体路径
|
// 根据配置读取怪物预制体路径
|
||||||
var path = "game/heros/"+HeroInfo[uuid].path;
|
var path = "game/heros/" + HeroInfo[uuid].path;
|
||||||
|
|
||||||
// 优先从对象池取节点,未命中时再实例化
|
// 优先从对象池取节点,未命中时再实例化
|
||||||
let node = Monster.getFromPool(path);
|
let node = Monster.getFromPool(path);
|
||||||
if (!node) {
|
if (!node) {
|
||||||
@@ -157,7 +157,7 @@ export class Monster extends ecs.Entity {
|
|||||||
if (collider) {
|
if (collider) {
|
||||||
collider.enabled = false;
|
collider.enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let baseScale = (node as any)._baseScale || v3(1, 1, 1);
|
let baseScale = (node as any)._baseScale || v3(1, 1, 1);
|
||||||
node.setScale(size * baseScale.x, size * baseScale.y);
|
node.setScale(size * baseScale.x, size * baseScale.y);
|
||||||
node.setPosition(pos)
|
node.setPosition(pos)
|
||||||
@@ -191,8 +191,8 @@ export class Monster extends ecs.Entity {
|
|||||||
model.revive = hero.revive;
|
model.revive = hero.revive;
|
||||||
|
|
||||||
// 标记是否 Boss,非 Boss 默认记作杂兵
|
// 标记是否 Boss,非 Boss 默认记作杂兵
|
||||||
model.is_boss =is_boss
|
model.is_boss = is_boss
|
||||||
if(!model.is_boss){
|
if (!model.is_boss) {
|
||||||
model.is_kalami = true;
|
model.is_kalami = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ export class Monster extends ecs.Entity {
|
|||||||
const skill = hero.skills[key];
|
const skill = hero.skills[key];
|
||||||
if (!skill) continue;
|
if (!skill) continue;
|
||||||
// 最终技能等级 = 初始技能等级 + 怪物等级增量,且下限为 0
|
// 最终技能等级 = 初始技能等级 + 怪物等级增量,且下限为 0
|
||||||
model.skills[skill.uuid] = { ...skill, lv: Math.max(0,skill.lv + mon_lv - 2), ccd: 0 };
|
model.skills[skill.uuid] = { ...skill, lv: Math.max(0, skill.lv + mon_lv - 2), ccd: 0 };
|
||||||
}
|
}
|
||||||
// 【测试模式专属】如果有覆盖技能配置则应用
|
// 【测试模式专属】如果有覆盖技能配置则应用
|
||||||
const testSkills = (this as any)._testSkills;
|
const testSkills = (this as any)._testSkills;
|
||||||
@@ -227,15 +227,24 @@ export class Monster extends ecs.Entity {
|
|||||||
if (testSkills.fend !== undefined) model.fend = testSkills.fend;
|
if (testSkills.fend !== undefined) model.fend = testSkills.fend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 按怪物等级 resolve 触发技能/复活到运行时缓存(怪物无 lv 成长,恒用 mon_lv)
|
||||||
|
model.runtime_call = resolveTriggerByLv(model.call, mon_lv);
|
||||||
|
model.runtime_dead = resolveTriggerByLv(model.dead, mon_lv);
|
||||||
|
model.runtime_fstart = resolveTriggerByLv(model.fstart, mon_lv);
|
||||||
|
model.runtime_fend = resolveTriggerByLv(model.fend, mon_lv);
|
||||||
|
model.runtime_atking = resolveTriggerByLv(model.atking, mon_lv);
|
||||||
|
model.runtime_atked = resolveTriggerByLv(model.atked, mon_lv);
|
||||||
|
model.runtime_revive = resolveReviveByLv(model.revive, mon_lv);
|
||||||
|
|
||||||
// 缓存技能射程等派生数据,减少战斗帧内重复计算
|
// 缓存技能射程等派生数据,减少战斗帧内重复计算
|
||||||
model.updateSkillDistanceCache();
|
model.updateSkillDistanceCache();
|
||||||
|
|
||||||
// 注册视图组件并重置对象池复用状态
|
// 注册视图组件并重置对象池复用状态
|
||||||
this.add(view);
|
this.add(view);
|
||||||
view.init();
|
view.init();
|
||||||
view.as.idle();
|
view.as.idle();
|
||||||
// 广播怪物加载事件,供刷怪与战斗系统联动
|
// 广播怪物加载事件,供刷怪与战斗系统联动
|
||||||
oops.message.dispatchEvent("monster_load",this)
|
oops.message.dispatchEvent("monster_load", this)
|
||||||
// 初始化移动参数:方向、目标 X、站位基准 Y
|
// 初始化移动参数:方向、目标 X、站位基准 Y
|
||||||
const move = this.get(MonMoveComp);
|
const move = this.get(MonMoveComp);
|
||||||
move.reset();
|
move.reset();
|
||||||
@@ -246,7 +255,7 @@ export class Monster extends ecs.Entity {
|
|||||||
|
|
||||||
// 依据下落距离自适应入场时长,确保观感一致
|
// 依据下落距离自适应入场时长,确保观感一致
|
||||||
const dropDistance = Math.abs(pos.y - dropToY);
|
const dropDistance = Math.abs(pos.y - dropToY);
|
||||||
|
|
||||||
const onDropComplete = () => {
|
const onDropComplete = () => {
|
||||||
if (!node || !node.isValid) return;
|
if (!node || !node.isValid) return;
|
||||||
// 落地后锁定最终位置,切换到落地完成状态
|
// 落地后锁定最终位置,切换到落地完成状态
|
||||||
@@ -271,7 +280,7 @@ export class Monster extends ecs.Entity {
|
|||||||
|
|
||||||
// 停止旧动画后执行下落 tween,避免复用节点时动画叠加
|
// 停止旧动画后执行下落 tween,避免复用节点时动画叠加
|
||||||
Tween.stopAllByTarget(node);
|
Tween.stopAllByTarget(node);
|
||||||
|
|
||||||
if (dropDistance > 0) {
|
if (dropDistance > 0) {
|
||||||
const dropDuration = Math.max(0.18, Math.min(0.38, dropDistance / 1200));
|
const dropDuration = Math.max(0.18, Math.min(0.38, dropDistance / 1200));
|
||||||
tween(node)
|
tween(node)
|
||||||
@@ -287,10 +296,10 @@ export class Monster extends ecs.Entity {
|
|||||||
smc.vmdata.mission_data.mon_num++
|
smc.vmdata.mission_data.mon_num++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 重置入口:复用 destroy 的释放流程 */
|
/** 重置入口:复用 destroy 的释放流程 */
|
||||||
reset() {
|
reset() {
|
||||||
super.destroy();
|
super.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,10 +42,10 @@ export class SkillTriggerHelper {
|
|||||||
this.handleDead(model, view);
|
this.handleDead(model, view);
|
||||||
break;
|
break;
|
||||||
case SkillTriggerType.FStart:
|
case SkillTriggerType.FStart:
|
||||||
this.handleArrayTrigger(model.fstart, model, view, type);
|
this.handleArrayTrigger(model.runtime_fstart, model, view, type);
|
||||||
break;
|
break;
|
||||||
case SkillTriggerType.FEnd:
|
case SkillTriggerType.FEnd:
|
||||||
this.handleArrayTrigger(model.fend, model, view, type);
|
this.handleArrayTrigger(model.runtime_fend, model, view, type);
|
||||||
break;
|
break;
|
||||||
case SkillTriggerType.Atking:
|
case SkillTriggerType.Atking:
|
||||||
this.handleAtking(model, view);
|
this.handleAtking(model, view);
|
||||||
@@ -61,17 +61,17 @@ export class SkillTriggerHelper {
|
|||||||
* 支持受【召唤强化羁绊 (SummonCount)】的多次触发加成。
|
* 支持受【召唤强化羁绊 (SummonCount)】的多次触发加成。
|
||||||
*/
|
*/
|
||||||
private static handleCall(model: HeroAttrsComp, view: HeroViewComp) {
|
private static handleCall(model: HeroAttrsComp, view: HeroViewComp) {
|
||||||
if (!model.call || model.call.length === 0) return;
|
if (!model.runtime_call || model.runtime_call.length === 0) return;
|
||||||
|
|
||||||
let triggerCount = 1;
|
let triggerCount = 1;
|
||||||
// 仅英雄享受加成,怪物始终只触发 1 次
|
// 仅英雄享受加成,怪物始终只触发 1 次
|
||||||
if (model.fac === FacSet.HERO) {
|
if (model.fac === FacSet.HERO) {
|
||||||
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.SummonCount);
|
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.SummonCount);
|
||||||
}
|
}
|
||||||
triggerCount = Math.max(1, Math.floor(triggerCount)); // 确保最少触发 1 次
|
triggerCount = Math.max(1, Math.floor(triggerCount)); // 确保最少触发 1 次
|
||||||
|
|
||||||
for (let i = 0; i < triggerCount; i++) {
|
for (let i = 0; i < triggerCount; i++) {
|
||||||
this.dispatchArray(model.call, model, view, SkillTriggerType.Call);
|
this.dispatchArray(model.runtime_call, model, view, SkillTriggerType.Call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,18 +80,18 @@ export class SkillTriggerHelper {
|
|||||||
* 支持受【亡语强化羁绊 (DeadCount)】的多次触发加成。
|
* 支持受【亡语强化羁绊 (DeadCount)】的多次触发加成。
|
||||||
*/
|
*/
|
||||||
private static handleDead(model: HeroAttrsComp, view: HeroViewComp) {
|
private static handleDead(model: HeroAttrsComp, view: HeroViewComp) {
|
||||||
if (!model.dead || model.dead.length === 0) return;
|
if (!model.runtime_dead || model.runtime_dead.length === 0) return;
|
||||||
|
|
||||||
let triggerCount = 1;
|
let triggerCount = 1;
|
||||||
if (model.fac === FacSet.HERO) {
|
if (model.fac === FacSet.HERO) {
|
||||||
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.DeadCount);
|
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.DeadCount);
|
||||||
// 【局内战绩评分系统】统计死亡触发技能生效次数(用于局后防守评分结算)
|
// 【局内战绩评分系统】统计死亡触发技能生效次数(用于局后防守评分结算)
|
||||||
smc.vmdata.scores.dead_trigger_count += model.dead.length;
|
smc.vmdata.scores.dead_trigger_count += model.runtime_dead.length;
|
||||||
}
|
}
|
||||||
triggerCount = Math.max(1, Math.floor(triggerCount));
|
triggerCount = Math.max(1, Math.floor(triggerCount));
|
||||||
|
|
||||||
for (let i = 0; i < triggerCount; i++) {
|
for (let i = 0; i < triggerCount; i++) {
|
||||||
this.dispatchArray(model.dead, model, view, SkillTriggerType.Dead);
|
this.dispatchArray(model.runtime_dead, model, view, SkillTriggerType.Dead);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,15 +100,15 @@ export class SkillTriggerHelper {
|
|||||||
* 判定逻辑:依据配置中的 t_num(触发所需普攻次数),对比当前的普攻累计次数取模判定。
|
* 判定逻辑:依据配置中的 t_num(触发所需普攻次数),对比当前的普攻累计次数取模判定。
|
||||||
*/
|
*/
|
||||||
private static handleAtking(model: HeroAttrsComp, view: HeroViewComp) {
|
private static handleAtking(model: HeroAttrsComp, view: HeroViewComp) {
|
||||||
if (!model.atking || model.atking.length === 0) return;
|
if (!model.runtime_atking || model.runtime_atking.length === 0) return;
|
||||||
|
|
||||||
let triggerCount = 1;
|
let triggerCount = 1;
|
||||||
if (model.fac === FacSet.HERO) {
|
if (model.fac === FacSet.HERO) {
|
||||||
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.AtkCount);
|
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.AtkCount);
|
||||||
}
|
}
|
||||||
triggerCount = Math.max(1, Math.floor(triggerCount));
|
triggerCount = Math.max(1, Math.floor(triggerCount));
|
||||||
|
|
||||||
model.atking.forEach(atkConfig => {
|
model.runtime_atking.forEach(atkConfig => {
|
||||||
// atk_count 代表已进行的普攻次数。当其余数刚好整除配置阈值时触发。
|
// atk_count 代表已进行的普攻次数。当其余数刚好整除配置阈值时触发。
|
||||||
if (model.atk_count > 0 && model.atk_count % atkConfig.t_num === 0) {
|
if (model.atk_count > 0 && model.atk_count % atkConfig.t_num === 0) {
|
||||||
for (let i = 0; i < triggerCount; i++) {
|
for (let i = 0; i < triggerCount; i++) {
|
||||||
@@ -123,15 +123,15 @@ export class SkillTriggerHelper {
|
|||||||
* 判定逻辑:依据配置中的 t_num(触发所需受击次数),对比当前的受击累计次数取模判定。
|
* 判定逻辑:依据配置中的 t_num(触发所需受击次数),对比当前的受击累计次数取模判定。
|
||||||
*/
|
*/
|
||||||
private static handleAtked(model: HeroAttrsComp, view: HeroViewComp) {
|
private static handleAtked(model: HeroAttrsComp, view: HeroViewComp) {
|
||||||
if (!model.atked || model.atked.length === 0) return;
|
if (!model.runtime_atked || model.runtime_atked.length === 0) return;
|
||||||
|
|
||||||
let triggerCount = 1;
|
let triggerCount = 1;
|
||||||
if (model.fac === FacSet.HERO) {
|
if (model.fac === FacSet.HERO) {
|
||||||
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.BeAtkCount);
|
triggerCount += FieldSkillHelper.getFieldSkillTotalValue(FieldSkillType.BeAtkCount);
|
||||||
}
|
}
|
||||||
triggerCount = Math.max(1, Math.floor(triggerCount));
|
triggerCount = Math.max(1, Math.floor(triggerCount));
|
||||||
|
|
||||||
model.atked.forEach(atkConfig => {
|
model.runtime_atked.forEach(atkConfig => {
|
||||||
// atked_count 代表已承受的受击次数。当其余数刚好整除配置阈值时触发。
|
// atked_count 代表已承受的受击次数。当其余数刚好整除配置阈值时触发。
|
||||||
if (model.atked_count > 0 && model.atked_count % atkConfig.t_num === 0) {
|
if (model.atked_count > 0 && model.atked_count % atkConfig.t_num === 0) {
|
||||||
for (let i = 0; i < triggerCount; i++) {
|
for (let i = 0; i < triggerCount; i++) {
|
||||||
@@ -144,7 +144,7 @@ export class SkillTriggerHelper {
|
|||||||
/**
|
/**
|
||||||
* 通用的数组型触发器处理(适用于 FStart / FEnd 等无需额外判定的简单列表触发)
|
* 通用的数组型触发器处理(适用于 FStart / FEnd 等无需额外判定的简单列表触发)
|
||||||
*/
|
*/
|
||||||
private static handleArrayTrigger(configs: {s_uuid: number, t_num: number, overrides?: SkillOverrides}[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
private static handleArrayTrigger(configs: { s_uuid: number, t_num: number, overrides?: SkillOverrides }[] | undefined, model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||||
if (!configs || configs.length === 0) return;
|
if (!configs || configs.length === 0) return;
|
||||||
this.dispatchArray(configs, model, view, type);
|
this.dispatchArray(configs, model, view, type);
|
||||||
}
|
}
|
||||||
@@ -152,7 +152,7 @@ export class SkillTriggerHelper {
|
|||||||
/**
|
/**
|
||||||
* 批量派发技能事件
|
* 批量派发技能事件
|
||||||
*/
|
*/
|
||||||
private static dispatchArray(configs: {s_uuid: number, t_num?: number, overrides?: SkillOverrides}[], model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
private static dispatchArray(configs: { s_uuid: number, t_num?: number, overrides?: SkillOverrides }[], model: HeroAttrsComp, view: HeroViewComp, type: SkillTriggerType) {
|
||||||
configs.forEach(config => this.dispatchSingle(config.s_uuid, model, view, type, config.overrides));
|
configs.forEach(config => this.dispatchSingle(config.s_uuid, model, view, type, config.overrides));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -438,10 +438,11 @@ export class HeroBoxComp extends CCComp {
|
|||||||
const finalCritDmg = this.model.getFinalCritDamage();
|
const finalCritDmg = this.model.getFinalCritDamage();
|
||||||
this.setStatRow(this.crit_dmg_all_label, this.crit_dmg_plus_label, finalCritDmg, finalCritDmg - (this.model.crit_damage ?? 0), "%");
|
this.setStatRow(this.crit_dmg_all_label, this.crit_dmg_plus_label, finalCritDmg, finalCritDmg - (this.model.crit_damage ?? 0), "%");
|
||||||
|
|
||||||
// ---- 技能描述(当前等级触发技能,读运行时 model 最终配置;数值富文本高亮) ----
|
// ---- 技能描述(全档位合并:每技能一行,等级置前 + 已/未激活状态,数值富文本高亮) ----
|
||||||
if (this.skill_label && this.skill_label.isValid) {
|
if (this.skill_label && this.skill_label.isValid) {
|
||||||
// 缓存未变则跳过重设,避免 refresh 降频内 RichText 重复重解析排版;隐藏「技能名」仅保留效果描述
|
// 缓存未变则跳过重设,避免 refresh 降频内 RichText 重复重解析排版
|
||||||
const desc = buildSkillDescRich(this.model, false);
|
// showName=false 不显示技能名仅保留效果;showLocked=true 合并全档位(未来档数值灰色拼接,未激活技能整行灰色)
|
||||||
|
const desc = buildSkillDescRich(this.model, false, true);
|
||||||
if (desc !== this.skillDescCache) {
|
if (desc !== this.skillDescCache) {
|
||||||
this.skillDescCache = desc;
|
this.skillDescCache = desc;
|
||||||
this.skill_label.string = desc;
|
this.skill_label.string = desc;
|
||||||
|
|||||||
@@ -304,14 +304,14 @@ export interface GeneratedMonster {
|
|||||||
/** 该波触发的波次强化 id 列表 */
|
/** 该波触发的波次强化 id 列表 */
|
||||||
wave_enchants: string[];
|
wave_enchants: string[];
|
||||||
|
|
||||||
/** 测试模式专用技能覆盖 */
|
/** 测试模式专用技能覆盖(按 s_uuid 分组 + lv 数组,与 heroInfo 结构一致) */
|
||||||
testSkills?: {
|
testSkills?: {
|
||||||
skill?: { s_uuid: number; cd?: number; overrides?: any };
|
skill?: { s_uuid: number; cd?: number; overrides?: any };
|
||||||
atking?: { s_uuid: number; t_num: number; overrides?: any }[];
|
atking?: Record<number, { lv: number; t_num: number; overrides?: any }[]>;
|
||||||
atked?: { s_uuid: number; t_num: number; overrides?: any }[];
|
atked?: Record<number, { lv: number; t_num: number; overrides?: any }[]>;
|
||||||
dead?: { s_uuid: number; t_num: number; overrides?: any }[];
|
dead?: Record<number, { lv: number; t_num: number; overrides?: any }[]>;
|
||||||
fstart?: { s_uuid: number; t_num: number; overrides?: any }[];
|
fstart?: Record<number, { lv: number; t_num: number; overrides?: any }[]>;
|
||||||
fend?: { s_uuid: number; t_num: number; overrides?: any }[];
|
fend?: Record<number, { lv: number; t_num: number; overrides?: any }[]>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,11 +334,11 @@ export const TestModeConfig = {
|
|||||||
testWaveEnchant: undefined as string | undefined,
|
testWaveEnchant: undefined as string | undefined,
|
||||||
|
|
||||||
skill: undefined as { s_uuid: number; cd?: number; overrides?: any } | undefined,
|
skill: undefined as { s_uuid: number; cd?: number; overrides?: any } | undefined,
|
||||||
atking: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined,
|
atking: undefined as Record<number, { lv: number; t_num: number; overrides?: any }[]> | undefined,
|
||||||
atked: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined,
|
atked: undefined as Record<number, { lv: number; t_num: number; overrides?: any }[]> | undefined,
|
||||||
dead: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined,
|
dead: undefined as Record<number, { lv: number; t_num: number; overrides?: any }[]> | undefined,
|
||||||
fstart: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined,
|
fstart: undefined as Record<number, { lv: number; t_num: number; overrides?: any }[]> | undefined,
|
||||||
fend: undefined as { s_uuid: number; t_num: number; overrides?: any }[] | undefined,
|
fend: undefined as Record<number, { lv: number; t_num: number; overrides?: any }[]> | undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
// ======================== 10. 生成引擎 ========================
|
// ======================== 10. 生成引擎 ========================
|
||||||
|
|||||||
Reference in New Issue
Block a user