Files
pixelheros/assets/script/game/common/config/heroSet.ts
panFD c59ba45b5b refactor: 统一将游戏内的「波次」术语替换为「回合」
本次提交将全项目中所有与「波次」相关的术语、注释、配置描述、UI文本全部替换为「回合」,包括:
1.  技能卡牌、怪物刷新、经济系统的相关注释与变量名
2.  配置表中的波次相关常量与描述文本
3.  UI预制体中的波次显示文本
4.  所有相关的文档注释与接口说明

统一术语后,游戏的关卡流程描述将更符合常规肉鸽游戏的表达习惯,避免与「波次」字面含义混淆,提升代码可读性与团队协作一致性。
2026-08-09 14:51:48 +08:00

1451 lines
70 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { v3 } from "cc"
import { BoxSet, FacSet, FightSet } from "./GameSet"
import { SkillOverrides, TGroup, SkillSet, FieldSkillSet, SkillConfig, SkillKind, FieldSkillConfig, FieldSkillType, mergeSkillParams } from "./SkillSet"
import { BuffList, BuffConfig, ModOp } from "./BuffSet"
import { Attrs } from "./HeroAttrs"
export enum HType {
Melee = 0,
Mid = 1,
Long = 2,
}
export const HTypeName = {
0: "近战",
1: "中程",
2: "远程",
}
export enum MonType {
Melee = 0,
Heavy = 1,
Long = 2,
Support = 3,
Summoner = 5,
Assassin = 6,
MeleeBoss = 8,
LongBoss = 9,
}
export const MonTypeName: Record<number, string> = {
[MonType.Melee]: "近战",
[MonType.Heavy]: "重型",
[MonType.Long]: "远程",
[MonType.Support]: "辅助",
[MonType.Summoner]: "召唤师",
[MonType.Assassin]: "刺客",
[MonType.MeleeBoss]: "近战Boss",
[MonType.LongBoss]: "远程Boss",
}
/**
* 英雄攻击速度分级配置 (数值为攻击间隔cd越小越快)
* 每档3个速度级别Lv1(最快) → Lv2(中间) → Lv3(最慢)
* 6档共18级覆盖所有英雄/怪物的攻击间隔
*/
export enum AtkSpeedLv {
VeryFast1 = 1, VeryFast2 = 2, VeryFast3 = 3,
Fast1 = 4, Fast2 = 5, Fast3 = 6,
Normal1 = 7, Normal2 = 8, Normal3 = 9,
Mid1 = 10, Mid2 = 11, Mid3 = 12,
Slow1 = 13, Slow2 = 14, Slow3 = 15,
VerySlow1 = 16, VerySlow2 = 17, VerySlow3 = 18,
}
export const AtkSpeedSet = {
[AtkSpeedLv.VeryFast1]: { name: "极速++", cd: 0.15 },
[AtkSpeedLv.VeryFast2]: { name: "极速+", cd: 0.20 },
[AtkSpeedLv.VeryFast3]: { name: "极速", cd: 0.30 },
[AtkSpeedLv.Fast1]: { name: "快速++", cd: 0.40 },
[AtkSpeedLv.Fast2]: { name: "快速+", cd: 0.50 },
[AtkSpeedLv.Fast3]: { name: "快速", cd: 0.70 },
[AtkSpeedLv.Normal1]: { name: "中速++", cd: 0.80 },
[AtkSpeedLv.Normal2]: { name: "中速+", cd: 0.90 },
[AtkSpeedLv.Normal3]: { name: "中速", cd: 1.00 },
[AtkSpeedLv.Mid1]: { name: "一般+", cd: 1.10 },
[AtkSpeedLv.Mid2]: { name: "一般", cd: 1.20 },
[AtkSpeedLv.Mid3]: { name: "一般-", cd: 1.30 },
[AtkSpeedLv.Slow1]: { name: "慢", cd: 1.50 },
[AtkSpeedLv.Slow2]: { name: "慢+", cd: 1.60 },
[AtkSpeedLv.Slow3]: { name: "慢++", cd: 1.80 },
[AtkSpeedLv.VerySlow1]: { name: "很慢", cd: 2.30 },
[AtkSpeedLv.VerySlow2]: { name: "很慢+", cd: 2.50 },
[AtkSpeedLv.VerySlow3]: { name: "很慢++", cd: 2.80 },
};
export const HeroPos = {
0: { pos: v3(-320, BoxSet.GAME_LINE, 0) },
1: { pos: v3(0, BoxSet.GAME_LINE, 0) },
2: { pos: v3(0, BoxSet.GAME_LINE, 0) },
}
export const FormationPointX = {
[HType.Melee]: -20,
[HType.Mid]: 100,
[HType.Long]: 100,
} as const;
export const HeroDisVal: Record<HType.Melee | HType.Mid | HType.Long, number> = {
[HType.Melee]: 120,
[HType.Mid]: 720,
[HType.Long]: 720,
}
export const resolveFormationTargetX = (fac: FacSet, type: HType): number => {
const resolvedRangeType = type as HType.Melee | HType.Mid | HType.Long;
const side = fac === FacSet.MON ? 1 : -1;
return FormationPointX[resolvedRangeType] * side;
}
export enum MonStart {
SLINE_1 = 140, //上线y
SLINE_2 = 100, //下线y
SLINE_3 = 180, //下线y
SLINE_4 = 60, //y起始点
START_X = 320, //x起始点
START_I = 90, //x轴间隔
}
/**
* 特殊触发技能类型
*/
export enum SkillTriggerType {
Call = "call", // 召唤后触发 降临
Dead = "dead", // 死亡后触发 遗志
FStart = "fstart", // 战斗开始 先手
FEnd = "fend", // 战斗结束 终战
Field = "field", // 驻场 光环
Atking = "atking", // 攻击后触发 追击
Atked = "atked", // 受击后触发 反击
Revive = "revive", // 复活触发 涅槃
}
export const SkillTriggerName = {
[SkillTriggerType.Call]: "召唤",
[SkillTriggerType.Dead]: "死亡后",
[SkillTriggerType.FStart]: "回合开始",
[SkillTriggerType.FEnd]: "回合结束",
[SkillTriggerType.Field]: "光环",
[SkillTriggerType.Atking]: "攻击",
[SkillTriggerType.Atked]: "受伤",
[SkillTriggerType.Revive]: "复活",
}
export const SkillTriggerDesc = {
[SkillTriggerType.Call]: "召唤时",
[SkillTriggerType.Dead]: "死亡时",
[SkillTriggerType.FStart]: "战斗开始时",
[SkillTriggerType.FEnd]: "战斗结束时",
[SkillTriggerType.Field]: "光环",
[SkillTriggerType.Atking]: "攻击n次",
[SkillTriggerType.Atked]: "受伤n次",
[SkillTriggerType.Revive]: "复活时",
}
/**
* 技能等级枚举(与英雄等级同标尺 1~5
* 配置触发技能档位时填入,表达"英雄升到 lv 级 → 该技能提升到 s_lv 级"的成长节奏,
* 与 LvTriggerEntry.lv 并列展示,便于 UI 面板显示"技能Lv.x"。
*/
export enum SkillLv {
Lv1 = 1,
Lv2 = 2,
Lv3 = 3,
Lv4 = 4,
Lv5 = 5,
}
/**
* 触发技能标准命名表(按触发方式 → 技能ID 分组命名)。
* 同一技能在不同触发语境下使用不同名称,贴合流派语义:
* atked=战士反击系 / atking=刺客·射手追击系 / dead=死亡遗产系 / fstart=法师战吼系 / revive=涅槃。
* 命名参考主流 Roguelike/自走棋技能风格(盾墙、复仇、嗜血、战吼、遗志、凤凰涅槃等)。
*/
export const TriggerSkillNameSet: Record<string, Record<number, string>> = {
[SkillTriggerType.Atked]: {
6301: "不屈壁垒", // 受击获得护盾,越挨打越硬
6302: "嗜血反击", // 受击恢复生命
6401: "愈战愈勇", // 受击永久提升攻击
6402: "钢筋铁骨", // 受击永久提升生命
6403: "复仇之心", // 受击限时提升暴击
6404: "以牙还牙", // 受击限时提升暴伤
6405: "震慑反扑", // 受击限时提升击晕
},
[SkillTriggerType.Atking]: {
6301: "攻守兼备", // 攻击为自己叠加护盾
6302: "治愈祷言", // 攻击治疗低血队友
6401: "嗜血连击", // 攻击永久提升攻击(滚雪球)
6403: "致命节奏", // 攻击限时提升暴击
6404: "猎手直觉", // 攻击提升暴伤
},
[SkillTriggerType.Dead]: {
6301: "守护遗志", // 死亡全队获得护盾
6401: "英魂永驻", // 死亡全队提升攻击
6402: "生命馈赠", // 死亡全队提升生命
6403: "致命遗产", // 死亡全队提升暴击
6404: "破灭遗产", // 死亡全队提升暴伤
6405: "震撼遗言", // 死亡全队提升击晕
},
[SkillTriggerType.FStart]: {
6301: "圣光护盾", // 开局全队护盾
6401: "破晓战吼", // 开局全队攻击提升
6402: "活力祝福", // 开局全队生命提升
},
[SkillTriggerType.Revive]: {
6501: "凤凰涅槃", // 死亡后原地复活
},
}
/**
* 查询触发技能在指定触发语境下的标准名称。
* @param type 触发类型SkillTriggerType
* @param s_uuid 技能ID
* @returns 语境专属名称;未配置时回退 SkillSet 通用名称
*/
export function getTriggerSkillName(type: SkillTriggerType, s_uuid: number): string {
return TriggerSkillNameSet[type]?.[s_uuid] ?? SkillSet[s_uuid]?.name ?? "";
}
/**
* 英雄/怪物基础信息接口
*/
export interface heroInfo {
uuid: number; // 唯一标识英雄5000段,怪物5200段
name: string; // 显示名称
icon?: string; // 图标名称(对应美术资源名)
path: string; // 资源路径(对应美术资源名)
fac: FacSet; // 阵营FacSet.HERO 或 FacSet.MON
kind?: number; // 未使用
lv: number; // 英雄等级
card_lv?: number; // 卡牌等级(驱动 bg_node 颜色1=green 2=blue 3=purple 4=red 5=yellow
type: HType; // 攻击定位(近战/中程/远程)
monType?: MonType; // 怪物专属类型
hp: number; // 生命值上限
ap: number; // 攻击力
[SkillTriggerType.Call]?: TriggerGrouped; // 召唤后触发的技能配置(按 s_uuid 分组,每组按 lv 升序)
[SkillTriggerType.Dead]?: TriggerGrouped; // 死亡后触发的技能配置
[SkillTriggerType.FStart]?: TriggerGrouped; // 战斗开始时释放的技能配置
[SkillTriggerType.FEnd]?: TriggerGrouped; // 战斗结束时释放的技能配置
[SkillTriggerType.Field]?: LvFieldEntry[]; // 驻场光环(按 lv 升序,运行时取 ≤英雄等级 的最大档)
[SkillTriggerType.Atking]?: TriggerGrouped; // 普通攻击后触发的技能配置s_uuid: 技能id, t_num: 触发所需的普攻次数
[SkillTriggerType.Atked]?: TriggerGrouped; // 受击后触发的技能配置s_uuid: 技能id, t_num: 触发所需的受击次数
[SkillTriggerType.Revive]?: LvReviveEntry[]; // 复活技能配置(按 lv 升序,运行时取 ≤英雄等级 的最大档)
dis?: number; // 攻击距离(像素)
speed?: number; // 移动速度(像素/秒)
skills: Record<number, HSkillInfo>; // 携带技能ID列表
ap_bonus?: LvBonusEntry[]; // 额外攻击加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档)
hp_bonus?: LvBonusEntry[]; // 额外生命加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档)
info: string; // 描述文案
/** 分级能力说明索引0=1级依次递增信息面板逐条展示各等级技能与能力 */
infos?: string[];
}
/**
* 技能基础信息接口
*/
export interface HSkillInfo {
uuid: number; // 唯一标识技能6000段等
lv: number; // 技能等级
cd: number; // 技能cd
ccd: number; // 占位当前cd用于cd计时
overrides?: SkillOverrides; // 角色专属参数覆盖
}
/**
* 触发技能单档配置:达到 lv 级时此档参数生效t_num/overrides 可随等级变化)。
* s_lv 标注此档对应的技能等级SkillLv 枚举),表达"英雄 lv 级 → 技能 s_lv 级"的成长节奏。
*/
export interface LvTriggerEntry {
lv: number; // 达到该英雄等级时解锁此档
s_lv?: SkillLv; // 此档对应的技能等级(标注用,便于面板显示"技能Lv.x"
t_num: number;
overrides?: SkillOverrides;
}
/**
* 触发技能按 s_uuid 分组的配置:每个 s_uuid 下按 lv 升序排列。
* 运行时取每个 s_uuid 中 ≤英雄等级 的最大 lv 档。
*/
export type TriggerGrouped = Record<number /*s_uuid*/, LvTriggerEntry[]>;
/**
* 驻场光环按等级解锁:运行时取 ≤英雄等级 的最大 lv 档的 uuids。
*/
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;
}
/*
*=============英雄配置列表================
* v4 触发类型底座版 — 每个英雄专注单一效果,流派协同由玩家自行发现
*
* atked 战士 受击触发,效果作用于自身,越挨打越强
* atking 刺客 攻击触发自身强化;射手 攻击触发队友强化hit_count 控制目标数 1→3→6
* dead 战士/刺客 死亡触发,一次性全队遗产
* fstart 法师 战斗开始前触发一次,必然生效的全队增益
* field 法师 驻场光环,存活期间持续生效,死亡消失
* fend 辅助 每回合结束触发,跨回合累积增益
*
* 触发节奏atked 3次/5次atking 5次/7次fstart/fend 1次/回合
*
* skills[0]是普通攻击技能
*/
export const HeroInfo: Record<number, heroInfo> = {
// ========== atked 类(战士 · 自身强化) ==========
5011: {
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 } },
// 成长主线:护盾层数 4→5→6等效减伤 57%→67%
atked: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 150 }, { lv: 5, value: 150 }],
ap_bonus: [{ lv: 5, value: 10 }],
info: "<color=#27AE60>✧</color>受伤获得护盾",
},
5012: {
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 } },
atked: {
6302: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 250 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 300 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 350 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 350 } },
],
6402: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
],
},
hp_bonus: [{ lv: 3, value: 150 }],
info: "<color=#27AE60>✧</color>受伤恢复生命",
},
5013: {
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 } },
atked: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } },
],
6402: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
],
},
hp_bonus: [{ lv: 3, value: 150 }],
info: "<color=#27AE60>✧</color>受伤获得护盾与生命",
},
5014: {
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 } },
atked: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } },
{ lv: 5, s_lv: SkillLv.Lv2, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } },
],
6403: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 150 }],
info: "<color=#27AE60>✧</color>受伤提升攻击与暴击",
},
5015: {
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 } },
atked: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 3 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 4 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 5 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 5 } },
],
6404: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 200 }],
info: "<color=#27AE60>✧</color>受伤获得护盾与暴伤",
},
5016: {
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 } },
atked: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 1 } },
{ lv: 5, s_lv: SkillLv.Lv2, t_num: 2, overrides: { TGroup: TGroup.Self, ap: 1 } },
],
6405: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } },
],
},
ap_bonus: [{ lv: 3, value: 20 }],
hp_bonus: [{ lv: 3, value: 150 }],
info: "<color=#27AE60>✧</color>受伤提升攻击与击晕",
},
// 以下英雄暂时注释,保留待后续扩展
// 5012:{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}},
// atked:[{s_uuid:6302,t_num:3,overrides:{TGroup:TGroup.Self,ap:250}}],
// info:"s3次为自身回复攻击力250%的生命值"},
// 5013:{uuid:5013,name:"铁骨头",path:"hk3", 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}},
// atked:[{s_uuid:6402,t_num:5,overrides:{TGroup:TGroup.Self,ap:100}}],
// info:"s5次永久提升自身最大生命值100点"},
// 5014:{uuid:5014,name:"怒火武者",path:"hk4", 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}},
// atked:[{s_uuid:6401,t_num:3,overrides:{TGroup:TGroup.Self,ap:12}}],
// info:"s3次永久提升自身攻击力12点"},
// 5015:{uuid:5015,name:"血刃武者",path:"hk5", 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}},
// atked:[
// {s_uuid:6301,t_num:3,overrides:{TGroup:TGroup.Self,ap:3}},
// {s_uuid:6401,t_num:5,overrides:{TGroup:TGroup.Self,ap:15}}
// ],
// info:"s3次加3层护盾s5次永久+15攻击力"},
// 5016:{uuid:5016,name:"狂血战士",path:"hc1", 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}},
// atked:[
// {s_uuid:6401,t_num:3,overrides:{TGroup:TGroup.Self,ap:10}},
// {s_uuid:6403,t_num:5,overrides:{TGroup:TGroup.Self,ap:15}}
// ],
// info:"s3次永久+10攻击力s5次永久+15%暴击率"},
// ========== atking 类 — 刺客(自身强化) ==========
5021: {
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 } },
// 成长主线滚雪球AP增量固定15级阈值5→4刀
atking: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } },
{ lv: 5, s_lv: SkillLv.Lv2, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } },
],
},
ap_bonus: [{ lv: 3, value: 20 }],
hp_bonus: [{ lv: 3, value: 80 }],
info: "<color=#27AE60>✧</color>攻击永久提升攻击",
},
5022: {
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 } },
atking: {
6403: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 5, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 4, overrides: { TGroup: TGroup.Self, hit_count: 1, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 1 } },
],
},
ap_bonus: [{ lv: 3, value: 20 }],
hp_bonus: [{ lv: 3, value: 80 }],
info: "<color=#27AE60>✧</color>攻击限时提升暴击",
},
5023: {
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 } },
atking: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } },
{ lv: 5, s_lv: SkillLv.Lv2, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 1 } },
],
6403: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 100 }],
info: "<color=#27AE60>✧</color>攻击提升攻击与暴击",
},
// 5022: {
// 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 } },
// atking: [
// { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 10 } },
// { s_uuid: 6401, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 12 } }
// ],
// info: "攻击5次永久+10%暴击率攻击7次永久+12攻击力"
// },
// 5023: {
// uuid: 5023, name: "暗影杀手", path: "hc3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, hp: 1500, ap: 142,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast1].cd, ccd: 0 } },
// atking: [
// { s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 10 } },
// { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Self, ap: 15 } }
// ],
// info: "攻击5次永久+10%暴击率攻击7次永久+15%暴伤"
// },
// ========== atking 类 — 射手队友强化hit_count 控制目标数) ==========
5031: {
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 } },
// 成长主线AP增益固定15级 hit_count 1→22英雄环境=全队)
atking: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } },
{ lv: 5, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 1 } },
],
},
hp_bonus: [{ lv: 3, value: 60 }],
info: "<color=#27AE60>✧</color>攻击提升队友攻击",
},
5032: {
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 } },
atking: {
6403: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } },
{ lv: 4, s_lv: SkillLv.Lv2, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
],
},
hp_bonus: [{ lv: 3, value: 80 }],
info: "<color=#27AE60>✧</color>攻击限时提升队友暴击",
},
// 5032: {
// uuid: 5032, name: "战术弓手", path: "ha2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
// atking: [{ s_uuid: 6403, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 10 } }],
// info: "攻击5次为随机3名队友永久提升暴击率10%"
// },
5033: {
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 } },
atking: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } },
{ lv: 4, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, ap: 1 } },
],
6404: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 100 }],
info: "<color=#27AE60>✧</color>攻击提升队友攻击与暴伤",
},
// 5033: {
// uuid: 5033, name: "鹰眼弓将", path: "ha3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast3].cd, ccd: 0 } },
// atking: [
// { s_uuid: 6401, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 6, ap: 8 } },
// { s_uuid: 6404, t_num: 7, overrides: { TGroup: TGroup.Team, hit_count: 6, ap: 12 } }
// ],
// info: "攻击5次为随机6名队友永久+8攻击力攻击7次永久+12%暴伤"
// },
// ========== dead 类(战士+刺客 · 死亡遗产) ==========
// 5041: {
// 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 } },
// dead: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } }],
// info: "死亡时为全队添加3层护盾"
// },
// 5042: {
// 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 } },
// dead: [
// { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } },
// { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 80 } }
// ],
// revive: { s_uuid: 6501, r_num: 1, upr: 0.3 },
// info: "死亡时全队永久+20攻击力、+80最大生命值死后复活一次"
// },
// 5043: {
// 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 } },
// dead: [{ s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } }],
// info: "死亡时全队永久提升击晕概率15%"
// },
// 5044: {
// 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 } },
// dead: [
// { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
// { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } }
// ],
// info: "死亡时全队永久+15%暴击率、+20%暴伤"
// },
// 5045: {
// uuid: 5045, name: "不灭战魂", path: "hk3", 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 } },
// dead: [
// { s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
// { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 30 } },
// { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 120 } }
// ],
// revive: { s_uuid: 6501, r_num: 1, upr: 0.5 },
// info: "死亡时全队获得5层护盾、永久+30攻击力、永久+120最大生命值死后复活一次"
// },
5041: {
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 } },
dead: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 100 }],
info: "<color=#27AE60>✧</color>死亡全队获得护盾",
},
5042: {
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 } },
dead: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
],
6402: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
],
},
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 },
],
info: "<color=#27AE60>✧</color>死亡全队攻血提升\n<color=#9B59B6>✦</color>死亡后原地复活",
},
5043: {
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 } },
dead: {
6405: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7017, buff_value: 10, buff_duration: 6 } },
],
6403: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 6 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 100 }],
info: "<color=#27AE60>✧</color>死亡全队击晕与暴击",
},
5044: {
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 } },
dead: {
6403: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
6404: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
{ lv: 4, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 7, buff_duration: 6 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
],
},
hp_bonus: [{ lv: 3, value: 150 }],
info: "<color=#27AE60>✧</color>死亡全队暴击与暴伤",
},
// ===== 5045 不灭战魂(已启用)=====
// 遗志双核心:死亡一次释放【盾+HP】双遗产
// 数值节奏:盾 5→6→7→8HP 10→12→15
5045: {
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 } },
// 死亡释放5 层护盾 + 全队 +10 HP复活 1 次血量 50%
dead: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } },
],
6402: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
],
},
revive: [
{ lv: 1, s_uuid: 6501, r_num: 1, upr: 0.5 },
{ lv: 3, s_uuid: 6501, r_num: 1, upr: 0.6 },
],
info: "<color=#27AE60>✧</color>死亡全队加护盾\n<color=#27AE60>✧</color>复活1:50%血量",
},
// ========== fstart 类(法师 · 战前增益) ==========
5051: {
uuid: 5051, name: "占卜师", path: "hm1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, hp: 143, ap: 40,
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
// 战前计时 buff每回合开始全队 AP 限时提升(+30/5s → +60/7s → +90/10s
// 统一复用 7111 基础配置,通过 buff_value/buff_duration 覆写实现三档成长
fstart: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 60, buff_duration: 7 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7111, buff_value: 90, buff_duration: 10 } },
],
},
hp_bonus: [{ lv: 2, value: 80 }, { lv: 4, value: 80 }],
info: "<color=#27AE60>✧</color>开局全队提升攻击",
},
5052: {
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 } },
fstart: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
],
6402: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } },
],
},
hp_bonus: [{ lv: 3, value: 80 }],
info: "<color=#27AE60>✧</color>开局全队获得护盾",
},
// 5052: {
// 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 } },
// fstart: [{ s_uuid: 6301, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 2 } }],
// info: "战斗开始时为全队添加2层护盾"
// },
// 5053: {
// uuid: 5053, name: "血盟法师", path: "hm3", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
// fstart: [{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 100 } }],
// info: "战斗开始时为全队永久提升最大生命值100点"
// },
// 5054: {
// uuid: 5054, name: "暴击法师", path: "hm4", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
// fstart: [{ s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } }],
// info: "战斗开始时为全队永久提升暴击率20%"
// },
// 5055: {
// uuid: 5055, name: "毁灭法师", path: "hm5", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, hp: 573, ap: 160,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid1].cd, ccd: 0 } },
// fstart: [
// { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 25 } },
// { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } }
// ],
// info: "战斗开始时为全队永久+25%暴伤、+20攻击力"
// },
// 5056: {
// uuid: 5056, name: "预言法师", path: "hm6", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
// fstart: [
// { s_uuid: 6405, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } },
// { s_uuid: 6403, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
// { s_uuid: 6404, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } }
// ],
// info: "战斗开始时为全队永久+20%击晕概率、+15%暴击率、+20%暴伤"
// },
// ========== field 类(法师 · 驻场光环) ==========
// 5061: {
// uuid: 5061, name: "亡语法师", path: "hm1", 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 } },
// field: [7015],
// info: "驻场期间全队死亡触发技能次数+1死亡后光环消失"
// },
5061: {
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 } },
field: [
{ lv: 1, uuids: [7002, 7006] },
{ lv: 2, uuids: [7202, 7006] },
{ lv: 4, uuids: [7202, 7206] },
],
hp_bonus: [{ lv: 3, value: 80 }],
info: "<color=#27AE60>✧</color>光环全队提升攻击\n<color=#9B59B6>✦</color>追加提升攻速",
},
// ========== fend + atking 类(辅助 · 治疗续航 + 回合增益) ==========
5071: {
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 } },
// 成长主线:治疗量 200→250→300%5级 hit_count 1→2全队
atking: {
6302: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } },
{ lv: 2, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } },
{ lv: 4, s_lv: SkillLv.Lv3, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 300 } },
{ lv: 5, s_lv: SkillLv.Lv4, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 300 } },
],
},
hp_bonus: [{ lv: 3, value: 80 }],
info: "<color=#27AE60>✧</color>攻击治疗低血队友",
},
// 5072: {
// uuid: 5072, name: "小金库", path: "hh2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, hp: 287, ap: 80,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid1].cd, ccd: 0 } },
// atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } }],
// fend: [{ s_uuid: 6303, t_num: 1, overrides: { gold: 1 } }],
// info: "攻击5次治疗全队每回合结束获得1金币"
// },
// 5073: {
// uuid: 5073, name: "强化牧师", path: "hh3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, hp: 430, ap: 120,
// 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: 250 } }],
// fend: [{ s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } }],
// info: "攻击5次治疗全队每回合结束全队永久+10攻击力"
// },
// 5074: {
// uuid: 5074, name: "生命牧师", path: "hh4", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, hp: 573, ap: 160,
// 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: 250 } }],
// fend: [{ s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 80 } }],
// info: "攻击5次治疗全队每回合结束全队永久+80最大生命值"
// },
// 5075: {
// uuid: 5075, name: "全能牧师", path: "hh5", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, hp: 717, ap: 200,
// skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } },
// atking: [{ s_uuid: 6302, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 300 } }],
// fend: [
// { s_uuid: 6401, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
// { s_uuid: 6402, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 60 } }
// ],
// info: "攻击5次治疗全队300%AP每回合结束全队永久+12攻击力、+60最大生命值"
// },
/*
*=============怪物配置列表================
* 基础近战型(lv:1) SPEED:800 |AP:12 | HP:360 | skills[0].cd=0.65
* 重型坦克型(lv:1) SPEED:800 |AP:30 | HP:1050 | skills[0].cd=2
* 远程dps(lv:1) SPEED:800 |AP:45 | HP:240 | skills[0].cd=1.5
* 远程辅助(lv:1) SPEED:800 |AP:20 | HP:240 | skills[0].cd=1
* 精英 (lv:1) SPEED:800 |AP:20 | HP:4500 | skills[0].cd=1
*/
// 基础怪物 (全部固定点位站桩攻击HType仅决定是前排还是后排)
// 前排怪物 (站在前排,承受更多伤害) — v5: TD节奏CD多而弱爽感设计
6001: {
uuid: 6001, name: "兽人战士", path: "m1", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 220, ap: 10, speed: 70,
skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "基础前排怪"
},
6002: {
uuid: 6002, name: "兽人精锐战士", path: "m2", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 300, ap: 14, speed: 110,
skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "进阶前排怪,更快更痛"
},
6003: {
uuid: 6003, name: "兽人重装兵", path: "m3", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Heavy, hp: 850, ap: 20, speed: 50,
skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "重型坦克怪高HP慢攻"
},
// 后排怪物 (站在后排,输出更高)
6004: {
uuid: 6004, name: "兽人射手", path: "m4", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Long, hp: 190, ap: 35, speed: 70,
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "后排高DPS怪"
},
6005: {
uuid: 6005, name: "兽人刺客", path: "m5", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Assassin, hp: 210, ap: 38, speed: 130,
skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "高AP快速攻击刺客"
},
// 特殊位怪物
6006: {
uuid: 6006, name: "骷髅领主", path: "m6", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.MeleeBoss, hp: 5000, ap: 20, speed: 60,
skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "前排MiniBoss级坦克"
},
6007: {
uuid: 6007, name: "兽人术士", path: "m7", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Support, hp: 300, ap: 24, speed: 70,
skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "后排法师怪,魔法攻击"
},
6008: {
uuid: 6008, name: "兽人火法", path: "m8", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Summoner, hp: 270, ap: 32, speed: 70,
skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "后排高输出法师怪"
},
// BOSS怪物 — Boss节奏1.2-1.5s删除不存在的6206技能
6101: {
uuid: 6101, name: "兽人首领-双刀战士", path: "mb1", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1900, ap: 30, speed: 120,
skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "前排Boss高攻速"
},
6102: {
uuid: 6102, name: "兽人首领-斧头战士", path: "mb2", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 7500, ap: 26, speed: 60,
skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "前排Boss超高HP"
},
6103: {
uuid: 6103, name: "兽人首领-魔法师", path: "mb3", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 2250, ap: 38, speed: 110,
skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow2].cd, ccd: 0 } }, info: "后排法系Boss高AP"
},
6104: {
uuid: 6104, name: "兽人首领-射手", path: "mb4", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 6800, ap: 30, speed: 70,
skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "后排位Boss均衡型"
},
6105: {
uuid: 6105, name: "亡灵首领-法师", path: "mb5", fac: FacSet.MON, lv: 6, type: HType.Long, monType: MonType.LongBoss, hp: 2600, ap: 42, speed: 110,
skills: { 6103: { uuid: 6103, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow1].cd, ccd: 0 } }, info: "后排高AP Boss"
},
6106: {
uuid: 6106, name: "亡灵首领-骑马战士", path: "mb6", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 9000, ap: 26, speed: 130,
skills: { 6005: { uuid: 6005, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow3].cd, ccd: 0 } }, info: "前排终极Boss最高HP+高速"
},
};
export const HeroList: number[] = [
// atked 类(战士 · 自身强化)
5011,
5012,
5013, 5014, 5015, 5016,
// atking 刺客(自身强化)
5021,
5022,
5023,
// atking 射手(队友强化)
5031,
5032,
5033,
// dead 类(死亡遗产)
5041, 5042, 5043, 5044,
5045,
// fstart 类(法师 · 战前增益)
5051,
5052,
// 5053, 5054, 5055, 5056,
// field 类(法师 · 驻场光环)
5061,
// fend + atking 类(辅助 · 治疗 + 回合增益)
5071,
// 5072, 5073, 5074, 5075,
];
// ==================== 英雄强度评分公式 ====================
/** 英雄强度公式调参权重(可在编辑器或运行时热调)
* 说明:
* - W_HP: 每 1 点生命值折算 1 分(生命值不随时间变化)
* - W_DPS_PER_SEC: 每 1 点 DPS 持续 1 秒折算 0.5 分
* (默认 60 秒评估窗下1 DPS ≈ 30 分,与旧版 W_DPS=30 等效)
* - WAVE_DURATION / HITS_PER_WAVE: 回合参数,用于估算 atked/fstart/fend/dead 触发次数
* - DEFAULT_EVAL_SECONDS: calcHeroPower 默认使用的评估时间窗
*/
export const HERO_POWER_WEIGHTS = {
W_HP: 1.0,
W_DPS_PER_SEC: 0.5,
W_atking: 1.0,
W_atked: 0.8,
W_fstart: 1.0,
W_fend: 1.2,
W_dead: 0.6,
W_field_alive: 1.0,
W_revive: 1.0,
W_heal: 0.8,
W_shield: 1.0,
W_control: 0.5,
expectedEnemyDmg: 20,
WAVE_DURATION: 30,
HITS_PER_WAVE: 10,
DEFAULT_EVAL_SECONDS: 60,
};
/**
* 解析触发技能在目标等级下的有效条目列表。
* 每个 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 } {
let hp = 0;
let ap = 0;
const lv = Math.max(1, targetLv);
if (hero.hp_bonus) {
for (const e of hero.hp_bonus) {
if (e.lv <= lv) hp += e.value;
}
}
if (hero.ap_bonus) {
for (const e of hero.ap_bonus) {
if (e.lv <= lv) ap += e.value;
}
}
return { hp, ap };
}
/** 计算目标等级下的有效 HP/AP含等级倍率与额外加成 */
function getEffectiveStats(hero: heroInfo, targetLv: number): { hp: number, ap: number } {
const bonuses = getEvolveBonuses(hero, targetLv);
const lv = Math.max(1, targetLv);
const multiplier = Math.pow(FightSet.HERO_LV_MULTIPLIER, lv - 1);
return {
hp: (hero.hp + bonuses.hp) * multiplier,
ap: (hero.ap + bonuses.ap) * multiplier,
};
}
/** 获取英雄普通攻击间隔(取 skills[0] 的 cd */
function getAttackCd(hero: heroInfo): number {
const skillIds = Object.keys(hero.skills);
if (skillIds.length === 0) return 1.0;
const firstKey = Number(skillIds[0]);
const skill = hero.skills[firstKey];
return skill?.cd || 1.0;
}
/** 计算目标群体范围系数 */
function calcScopeMul(group: TGroup): number {
return (group === TGroup.Ally || group === TGroup.Team) ? FightSet.HERO_MAX_NUM : 1;
}
/** 计算目标时间窗内的普攻次数 */
function getAttackCount(hero: heroInfo, seconds: number): number {
return seconds / getAttackCd(hero);
}
/** 计算目标时间窗内的受击次数 */
function getHitCount(seconds: number): number {
const weights = HERO_POWER_WEIGHTS;
return (seconds / weights.WAVE_DURATION) * weights.HITS_PER_WAVE;
}
/** 计算目标时间窗内的回合数 */
function getWaveCount(seconds: number): number {
return seconds / HERO_POWER_WEIGHTS.WAVE_DURATION;
}
/** 计算触发技在目标时间窗内的触发次数 */
function getTriggerCount(
type: SkillTriggerType,
t_num: number,
hero: heroInfo,
seconds: number
): number {
switch (type) {
case SkillTriggerType.Atking:
return getAttackCount(hero, seconds) / t_num;
case SkillTriggerType.Atked:
return getHitCount(seconds) / t_num;
case SkillTriggerType.FStart:
case SkillTriggerType.FEnd:
return getWaveCount(seconds);
case SkillTriggerType.Dead:
return getWaveCount(seconds) * (1 + (resolveReviveByLv(hero.revive, FightSet.HERO_MAX_LV)?.r_num || 0));
}
return 1;
}
/** 将计时 buff 折算为“在整个时间窗内持续生效”的等效价值 */
function calcBuffPermanentEquivalent(buff: BuffConfig, apEff: number, cd: number, seconds: number, buffValueOverride?: number): number {
const weights = HERO_POWER_WEIGHTS;
let value = 0;
if (buff.modifiers) {
for (const mod of buff.modifiers) {
const dps = apEff / cd;
const modValue = buffValueOverride ?? mod.value;
switch (mod.attr) {
case Attrs.ap:
if (mod.op === ModOp.Flat) {
value += (modValue / cd) * weights.W_DPS_PER_SEC * seconds;
} else if (mod.op === ModOp.PercentAdd) {
value += (modValue / 100) * dps * weights.W_DPS_PER_SEC * seconds;
}
break;
case Attrs.hp:
case Attrs.hp_max:
value += modValue * weights.W_HP;
break;
case Attrs.critical:
value += (modValue / 100) * dps * 0.5 * weights.W_DPS_PER_SEC * seconds;
break;
case Attrs.critical_damage:
value += (modValue / 100) * dps * 0.05 * weights.W_DPS_PER_SEC * seconds;
break;
case Attrs.speed:
value += (modValue / 100) * dps * weights.W_DPS_PER_SEC * seconds;
break;
}
}
}
if (buff.tick) {
const ticks = Math.max(1, buff.duration / buff.tick.interval);
const totalHeal = ticks * (buff.tick.damage_or_heal + (buff.tick.scale_by_ap_pct / 100) * apEff);
value += Math.max(0, totalHeal) * weights.W_heal;
}
return value;
}
/** 计算 Support 类技能单次触发的效果价值 */
function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number, seconds: number): number {
const weights = HERO_POWER_WEIGHTS;
const value = config.ap || 0;
// 计时 buff先算整个时间窗的永久等效再按覆盖率折算
if (config.timed_buff_id) {
const buff = BuffList[config.timed_buff_id];
if (buff) {
const permanentEquivalent = calcBuffPermanentEquivalent(buff, apEff, cd, seconds, config.buff_value);
const duration = config.buff_duration ?? buff.duration;
const uptime = seconds > 0 ? Math.min(duration / seconds, 1) : 0;
return permanentEquivalent * uptime;
}
}
switch (config.buff_type) {
case Attrs.ap:
return (value / cd) * weights.W_DPS_PER_SEC * seconds;
case Attrs.hp_max:
case Attrs.hp:
return value * weights.W_HP;
case Attrs.critical:
return (value / 100) * (apEff / cd) * 0.5 * weights.W_DPS_PER_SEC * seconds;
case Attrs.critical_damage:
return (value / 100) * (apEff / cd) * 0.05 * weights.W_DPS_PER_SEC * seconds;
case Attrs.stun_chance:
case Attrs.freeze_chance:
case Attrs.knockback_chance:
return value * weights.W_control;
case Attrs.speed:
return (value / 100) * (apEff / cd) * weights.W_DPS_PER_SEC * seconds;
default:
return value * weights.W_control;
}
}
/** 计算单条技能配置单次触发的效果价值 */
function calcSkillEffectValue(skill: SkillConfig, overrides: SkillOverrides | undefined, hero: heroInfo, targetLv: number, seconds: number): number {
const { ap: apEff } = getEffectiveStats(hero, targetLv);
const cd = getAttackCd(hero);
const config = overrides ? mergeSkillParams(skill, overrides) : skill;
const weights = HERO_POWER_WEIGHTS;
switch (config.kind) {
case SkillKind.Damage:
return ((config.ap || 0) / 100) * apEff * weights.W_DPS_PER_SEC;
case SkillKind.Heal:
return ((config.ap || 0) / 100) * apEff * weights.W_heal;
case SkillKind.Shield:
return (config.ap || 0) * weights.expectedEnemyDmg * weights.W_shield;
case SkillKind.Support:
return calcSupportEffectValue(config, apEff, cd, seconds);
default:
return 0;
}
}
/** 触发技评估项 */
export interface TriggerSkillEval {
type: SkillTriggerType;
s_uuid: number;
name: string;
t_num: number;
value: number;
}
/** 驻场光环评估项 */
export interface FieldSkillEval {
uuid: number;
name: string;
value: number;
}
/** 英雄强度分数构成 */
export interface HeroPowerBreakdown {
hp: number;
dps: number;
atking: number;
atked: number;
fstart: number;
fend: number;
dead: number;
field: number;
revive: number;
}
/** 英雄强度详细评估结果 */
export interface HeroPowerDetailed {
total: number;
breakdown: HeroPowerBreakdown;
triggerSkills: TriggerSkillEval[];
fieldSkills: FieldSkillEval[];
normalAttack: { s_uuid: number, name: string, cd: number, dps: number, value: number };
}
/** 计算普通触发类技能atking/atked/fstart/fend/dead的详细价值 */
function calcTriggerPowerDetailed(
triggerConfigs: { s_uuid: number, t_num?: number, overrides?: SkillOverrides }[],
hero: heroInfo,
targetLv: number,
type: SkillTriggerType,
seconds: number
): { total: number, items: TriggerSkillEval[] } {
if (!triggerConfigs || triggerConfigs.length === 0) return { total: 0, items: [] };
const weights = HERO_POWER_WEIGHTS;
let total = 0;
const items: TriggerSkillEval[] = [];
for (const trig of triggerConfigs) {
const skill = SkillSet[trig.s_uuid];
if (!skill) continue;
const effectValue = calcSkillEffectValue(skill, trig.overrides, hero, targetLv, seconds);
const overrides = trig.overrides || {};
const group = overrides.TGroup ?? skill.TGroup;
const scopeMul = calcScopeMul(group);
const tNum = trig.t_num || 1;
let weight = 1;
switch (type) {
case SkillTriggerType.Atking:
weight = weights.W_atking;
break;
case SkillTriggerType.Atked:
weight = weights.W_atked;
break;
case SkillTriggerType.FStart:
weight = weights.W_fstart;
break;
case SkillTriggerType.FEnd:
weight = weights.W_fend;
break;
case SkillTriggerType.Dead:
weight = weights.W_dead;
break;
}
const triggerCount = getTriggerCount(type, tNum, hero, seconds);
const value = effectValue * triggerCount * scopeMul * weight;
total += value;
items.push({ type, s_uuid: trig.s_uuid, name: skill.name, t_num: tNum, value });
}
return { total, items };
}
/** 计算驻场光环技能在时间窗内的总价值 */
function calcFieldSkillValue(field: FieldSkillConfig, hpEff: number, apEff: number, cd: number, scopeMul: number, seconds: number): number {
const weights = HERO_POWER_WEIGHTS;
const dps = apEff / cd;
switch (field.type) {
case FieldSkillType.HeroAtk:
return field.value * dps * scopeMul * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroHp:
return field.value * hpEff * scopeMul * weights.W_HP;
case FieldSkillType.HeroSpeed:
return field.value * dps * scopeMul * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroCrit:
return field.value * dps * scopeMul * 0.5 * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroCritDamage:
return field.value * dps * scopeMul * 0.05 * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroStun:
case FieldSkillType.HeroWindFury:
case FieldSkillType.HeroPuncture:
return field.value * scopeMul * weights.W_control * 100;
default:
return field.value * scopeMul * weights.W_control * 10;
}
}
/** 计算驻场光环的详细价值 */
function calcFieldPowerDetailed(fieldUuids: number[] | undefined, hero: heroInfo, targetLv: number, seconds: number): { total: number, items: FieldSkillEval[] } {
if (!fieldUuids || fieldUuids.length === 0) return { total: 0, items: [] };
const weights = HERO_POWER_WEIGHTS;
const { hp: hpEff, ap: apEff } = getEffectiveStats(hero, targetLv);
const cd = getAttackCd(hero);
const scopeMul = FightSet.HERO_MAX_NUM;
let total = 0;
const items: FieldSkillEval[] = [];
for (const uuid of fieldUuids) {
const field = FieldSkillSet[uuid];
if (!field) continue;
const value = calcFieldSkillValue(field, hpEff, apEff, cd, scopeMul, seconds) * weights.W_field_alive;
total += value;
items.push({ uuid, name: field.name, value });
}
return { total, items };
}
/** 获取普通攻击信息 */
function getNormalAttackInfo(hero: heroInfo, targetLv: number = 1, seconds: number = HERO_POWER_WEIGHTS.DEFAULT_EVAL_SECONDS): { s_uuid: number, name: string, cd: number, dps: number, value: number } {
const weights = HERO_POWER_WEIGHTS;
const { ap: apEff } = getEffectiveStats(hero, targetLv);
const cd = getAttackCd(hero);
const skillIds = Object.keys(hero.skills);
const firstKey = skillIds.length > 0 ? Number(skillIds[0]) : 0;
const skill = firstKey ? SkillSet[firstKey] : undefined;
const dps = apEff / cd;
return {
s_uuid: firstKey,
name: skill?.name ?? '普攻',
cd,
dps,
value: dps * weights.W_DPS_PER_SEC * seconds,
};
}
/**
* 计算英雄强度详细评估(含分数构成与每个技能价值)。
* @param hero 英雄/怪物配置
* @param targetLv 目标等级,默认 1
* @param seconds 评估时间窗(秒),默认 HERO_POWER_WEIGHTS.DEFAULT_EVAL_SECONDS
* @returns 详细强度评估结果
*/
export function calcHeroPowerDetailed(hero: heroInfo, targetLv: number = 1, seconds: number = HERO_POWER_WEIGHTS.DEFAULT_EVAL_SECONDS): HeroPowerDetailed {
const weights = HERO_POWER_WEIGHTS;
const { hp: hpEff, ap: apEff } = getEffectiveStats(hero, targetLv);
const cd = getAttackCd(hero);
const hpValue = hpEff * weights.W_HP;
const dpsValue = (apEff / cd) * weights.W_DPS_PER_SEC * seconds;
const normalAttack = getNormalAttackInfo(hero, targetLv, seconds);
const atking = hero.atking ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.atking, targetLv), hero, targetLv, SkillTriggerType.Atking, 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(resolveTriggerByLv(hero.fstart, targetLv), hero, targetLv, SkillTriggerType.FStart, 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(resolveTriggerByLv(hero.dead, targetLv), hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
const fieldUuids = resolveFieldByLv(hero.field, targetLv);
const field = fieldUuids.length > 0 ? calcFieldPowerDetailed(fieldUuids, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] };
let reviveValue = 0;
const revive = resolveReviveByLv(hero.revive, targetLv);
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;
return {
total,
breakdown: {
hp: hpValue,
dps: dpsValue,
atking: atking.total,
atked: atked.total,
fstart: fstart.total,
fend: fend.total,
dead: dead.total,
field: field.total,
revive: reviveValue,
},
triggerSkills: [...atking.items, ...atked.items, ...fstart.items, ...fend.items, ...dead.items],
fieldSkills: field.items,
normalAttack,
};
}
/**
* 计算指定时间窗内的英雄强度评分。
* @param hero 英雄/怪物配置
* @param targetLv 目标等级,默认 1
* @param seconds 评估时间窗(秒)
* @returns 无量纲强度分,数值越大越强
*/
export function calcHeroPowerOverTime(hero: heroInfo, targetLv: number = 1, seconds: number = HERO_POWER_WEIGHTS.DEFAULT_EVAL_SECONDS): number {
return calcHeroPowerDetailed(hero, targetLv, seconds).total;
}
/**
* 计算英雄强度评分(默认时间窗)。
* @param hero 英雄/怪物配置
* @param targetLv 目标等级,默认 1
* @returns 无量纲强度分,数值越大越强
*/
export function calcHeroPower(hero: heroInfo, targetLv: number = 1): number {
return calcHeroPowerOverTime(hero, targetLv);
}
/**
* 归一化英雄强度评分。
* @param hero 英雄配置
* @param targetLv 目标等级
* @param baseHeroId 基准英雄 uuid
* @param baseScore 基准分
* @returns 以基准英雄为 baseScore 的相对分数
*/
export function calcHeroPowerNormalized(hero: heroInfo, targetLv: number = 1, baseHeroId: number = 5011, baseScore: number = 100): number {
const baseHero = HeroInfo[baseHeroId];
if (!baseHero) return 0;
const basePower = calcHeroPower(baseHero, targetLv);
if (basePower === 0) return 0;
return calcHeroPower(hero, targetLv) / basePower * baseScore;
}