Files
pixelheros/assets/script/game/common/config/heroSet.ts
pan 2cc9678f74 fix(hero): 调整英雄技能配置与调试模式
1. 全局替换proc_skill技能结构为timed_buff相关配置
2. 修正技能参数数值与日志打印格式
3. 调整SCastSystem与CHeroComp的调试模式开关
2026-09-08 08:57:44 +08:00

1767 lines
90 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,越小越快)
* 5 档速度:最快 VeryFast 0.75s → 最慢 VerySlow 1.50s
*/
export enum AtkSpeedLv {
VeryFast = 1,
Fast = 2,
Normal = 3,
Slow = 4,
VerySlow = 5,
}
export const AtkSpeedSet = {
[AtkSpeedLv.VeryFast]: { name: "极速", cd: 0.75 },
[AtkSpeedLv.Fast]: { name: "快速", cd: 0.90 },
[AtkSpeedLv.Normal]: { name: "中速", cd: 1.05 },
[AtkSpeedLv.Slow]: { name: "慢速", cd: 1.20 },
[AtkSpeedLv.VerySlow]: { name: "极慢", cd: 1.50 },
};
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;
/** 各攻击定位的默认攻击距离(像素):近战100 / 中程300 / 远程450;英雄配置了 dis 时优先取配置值 */
export const HeroDisVal: Record<HType.Melee | HType.Mid | HType.Long, number> = {
[HType.Melee]: 100,
[HType.Mid]: 300,
[HType.Long]: 450,
}
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轴间隔
}
/**
* 英雄成长类型(决定每级 hp/ap 标准增量系数)。
* Why: 不同定位英雄的成长曲线差异化,避免"一刀切"导致坦克/刺客同强度。
*/
export enum HGrowType {
Tank = 0, // 坦克:高 hp 低 ap
Warrior = 1, // 战士:均衡
Assassin = 2, // 刺客:低 hp 高 ap
Mage = 3, // 法师:中 hp 高 ap
Support = 4, // 辅助:中 hp 低 ap
Archer = 5, // 射手:中低 hp 高 ap(持续物理输出)
}
/** 成长类型系数表(每级增量 = 英雄基础属性 × 对应系数) */
export const HERO_GROW_COEF: Record<HGrowType, { hp: number; ap: number; def: number }> = {
[HGrowType.Tank]: { hp: 1.5, ap: 0.6, def: 1.5 },
[HGrowType.Warrior]: { hp: 1.0, ap: 1.0, def: 1.0 },
[HGrowType.Assassin]: { hp: 0.7, ap: 1.4, def: 0.5 },
[HGrowType.Mage]: { hp: 0.9, ap: 1.3, def: 0.5 },
[HGrowType.Support]: { hp: 1.1, ap: 0.7, def: 1.0 },
[HGrowType.Archer]: { hp: 0.8, ap: 1.3, def: 0.5 },
};
/**
* 英雄品质系数步长:相邻品质(rarity)基础属性相差 5%。
* 系数 = 1 + HERO_QUALITY_STEP × (rarity - 1),lv1~lv5 → 1.00/1.05/1.10/1.15/1.20。
* 仅作用于 lv1 初始基础属性(AP/HP/DEF),成长与等级 bonus 不随品质缩放。
*/
export const HERO_QUALITY_STEP = 0.05;
/** 计算英雄品质系数(相邻品质基础属性差 5%) */
export function getHeroQualityCoef(rarity: number): number {
return 1 + HERO_QUALITY_STEP * (Math.max(1, rarity) - 1);
}
/**
* lv12 职业属性专项已移除:单项属性强化统一由英雄配置的 bonus 档位注入
* (如 { lv: 12, attrs: { ap: 50 } }),机制与展示口径保持一致。
*/
/** 英雄位置类型(职业定位)。
* Why: grow_type 仅驱动数值成长曲线,无法表达"这个英雄在阵容里干什么";
* role 面向 UI 展示与阵容推荐(如 HeroComboSet 的铁三角校验),与成长解耦。
*/
export enum HRole {
Tank = 0, // 坦克:前排承伤,受击发动机
Warrior = 1, // 战士:前排输出/献祭位
Assassin = 2, // 刺客:近战爆发主C
Archer = 3, // 射手:远程物理主C
Mage = 4, // 法师:远程先手增益
Support = 5, // 辅助:光环/治疗
}
export const HRoleName: Record<HRole, string> = {
[HRole.Tank]: "坦克",
[HRole.Warrior]: "战士",
[HRole.Assassin]: "刺客",
[HRole.Archer]: "射手",
[HRole.Mage]: "法师",
[HRole.Support]: "辅助",
};
/** lv12 职业专项已移除:单项强化由 bonus 配置接管,此处不再保留职业→属性映射 */
/**
* 职业基础属性模板(仅英雄使用,怪物无 role 直接手写 hp/ap/def)。
* 英雄配置处的 hp/ap/def = 本模板值 + 该卡手动增量,模板保证同职业基准一致、增量表达个体差异。
* Why: 局外升级机制将在加载时(Hero.ts / Mon.ts)统一重算属性,配置表只承担"基准+增量"的静态表达。
*/
export const HERO_ROLE_BASE: Record<HRole, { hp: number; ap: number; def: number }> = {
[HRole.Tank]: { hp: 600, ap: 20, def: 50 }, // 坦克:高防高血,前排承伤
[HRole.Warrior]: { hp: 560, ap: 22, def: 30 }, // 战士:均衡
[HRole.Assassin]: { hp: 560, ap: 22, def: 10 }, // 刺客:低防,近战爆发
[HRole.Archer]: { hp: 280, ap: 32, def: 10 }, // 射手:低防,远程物理主C
[HRole.Mage]: { hp: 280, ap: 32, def: 10 }, // 法师:低防,远程增益
[HRole.Support]: { hp: 280, ap: 32, def: 15 }, // 辅助:低防,光环/治疗
};
/**
* 计算英雄在目标等级下的累计属性成长增量(线性:每级加一份"基础属性×系数")。
* 公式:累计 = 基础属性 × 类型系数 × (lv - 1)。
* Why: 以英雄自身基础值为基数,自动适配低/高费卡的成长占比,避免全局固定值失衡;
* 线性曲线在无限升级下不会指数爆炸,强度平滑可控。
* @param hero 英雄配置(取 hp/ap/def 基础值与 grow_type)
* @param targetLv 目标等级(≥1)
* @returns 累计 hp/ap/def 增量(已取整)
*/
export function calcGrowBonus(hero: Pick<heroInfo, "hp" | "ap" | "def" | "grow_type">, targetLv: number): { hp: number; ap: number; def: number } {
const coef = HERO_GROW_COEF[hero.grow_type ?? HGrowType.Warrior];
const steps = Math.max(0, Math.floor(targetLv) - 1);
return {
hp: Math.floor(hero.hp * coef.hp * steps),
ap: Math.floor(hero.ap * coef.ap * steps),
def: Math.floor(hero.def * coef.def * steps),
};
}
/**
* 特殊触发技能类型
*/
export enum SkillTriggerType {
Call = "call", // 召唤后触发 降临
Dead = "dead", // 死亡后触发 遗志
FStart = "fstart", // 战斗开始 先手
Field = "field", // 驻场 光环
Atking = "atking", // 攻击后触发 追击
Atked = "atked", // 受击后触发 反击
Revive = "revive", // 复活触发 涅槃
}
export const SkillTriggerName = {
[SkillTriggerType.Call]: "召唤",
[SkillTriggerType.Dead]: "死亡后",
[SkillTriggerType.FStart]: "回合开始",
[SkillTriggerType.Field]: "光环",
[SkillTriggerType.Atking]: "攻击",
[SkillTriggerType.Atked]: "受伤",
[SkillTriggerType.Revive]: "复活",
}
export const SkillTriggerDesc = {
[SkillTriggerType.Call]: "召唤时",
[SkillTriggerType.Dead]: "死亡时",
[SkillTriggerType.FStart]: "战斗开始时",
[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,
}
/**
* 触发技能对外命名规则:
* 英雄除普攻外的技能(call/atked/atking/dead/fstart)命名统一收敛进各英雄 HeroInfo 配置
* (HSkillInfo.name 给普攻/主技能命名;LvTriggerEntry.name 给触发技能组命名,写在该组第 1 档)。
* UI 层将每个触发槽位(atking/dead/fstart/atked/call/field)整组视为一个技能:
* 组内多个 s_uuid / 光环词条合并为一个名称与一套说明统一展示,组名取组内首个自定义名。
* 天赋由 TalentSet 自行命名;SkillSet.name 仅作内部底座代号,不直接对外展示。
*/
/**
* 查询触发技能组的对外展示名(英雄语境,来自 HeroInfo 配置)。
* @param grouped 触发技能分组配置(某英雄某触发类型的 TriggerGrouped)
* @param s_uuid 技能ID
* @returns 该组第 1 档 name;未配置时回退 SkillSet 内部名
*/
export function getGroupedTriggerName(grouped: TriggerGrouped | undefined, s_uuid: number): string {
const entries = grouped?.[s_uuid];
if (entries?.length && entries[0].name) return entries[0].name;
return SkillSet[s_uuid]?.name ?? "";
}
/**
* 查询驻场光环词条的对外展示名(英雄语境,FieldEntry.name 优先,缺省回退 FieldSkillSet 底座名)。
* Why: 名称收敛进 heroSet 英雄配置,同一光环词条(如 7002 攻击光环)在不同英雄下可有特色名。
* @param hero 英雄配置(含 field 词条的 heroInfo)
* @param uuid 光环 uuid(指向 FieldSkillSet 底座)
*/
export function getFieldSkillName(hero: heroInfo | undefined, uuid: number): string {
for (const e of hero?.field ?? []) {
const entry = e.uuids.find(u => u.uuid === uuid);
if (entry?.name) return entry.name;
}
return FieldSkillSet[uuid]?.name ?? "";
}
/**
* 查询触发技能组(整个触发槽位)的对外统一展示名(英雄语境)。
* Why: 每个触发槽位整组视为一个技能,组内多个 s_uuid 合并展示,需要统一组名。
* @param hero 英雄配置
* @param type 触发槽位(call/dead/fstart/atking/atked)
* @returns 组内首个配置了 name 的条目名(按 s_uuid 与档位配置顺序扫描);
* 均未配置时回退组内首个 s_uuid 的 SkillSet 底座名;组不存在返回 ""
*/
export function getTriggerGroupName(hero: heroInfo | undefined, type: SkillTriggerType): string {
const grouped = hero?.[type] as TriggerGrouped | undefined;
if (!grouped) return "";
let firstUuid = 0;
for (const key in grouped) {
if (!firstUuid) firstUuid = Number(key);
const name = grouped[key]?.[0]?.name;
if (name) return name;
}
return firstUuid ? (SkillSet[firstUuid]?.name ?? "") : "";
}
/**
* 查询驻场光环组(hero.field 整体)的对外统一展示名(英雄语境)。
* Why: field 槽位同样整组视为一个技能,组内多个词条合并展示,组名取首个自定义名。
* @param hero 英雄配置(含 field 词条档位)
* @returns 全部档位词条中首个配置 name 的(按档位 lv 与词条顺序扫描);
* 均未配置时回退首个词条的 FieldSkillSet 底座名;无光环返回 ""
*/
export function getFieldGroupName(hero: heroInfo | undefined): string {
let firstUuid = 0;
for (const tier of hero?.field ?? []) {
for (const entry of tier.uuids) {
if (!firstUuid) firstUuid = entry.uuid;
if (entry.name) return entry.name;
}
}
return firstUuid ? (FieldSkillSet[firstUuid]?.name ?? "") : "";
}
/**
* 解析技能的对外展示图标(英雄语境):英雄/触发引用侧通过 overrides.icon 覆写时优先,
* 缺省回退 SkillSet 底座 icon;驻场光环词条统一取 FieldSkillSet 底座 icon。
* Why: 图标是"对外展示"维度(与数值覆写同一套注入机制),实现同一底座不同英雄/档位不同外观。
* @param hero 英雄配置
* @param skillUuid 技能 uuid(skills key / 触发组 s_uuid / FieldSkillSet uuid)
* @param slot 技能所属槽位(可空):指定时仅在该槽位查找;缺省按 普攻/大招→触发组 顺序定位
* @param isGroup 整组模式:true 时取组内首个 s_uuid 的图标(slot 必填,光环取首个词条)
* @returns 图标ID;未找到返回 undefined
*/
export function getHeroSkillIcon(hero: heroInfo | undefined, skillUuid: number, slot?: SkillTriggerType, isGroup: boolean = false): string | undefined {
if (!hero) return undefined;
// 整组模式:组内首个 s_uuid/词条的图标
if (isGroup && slot !== undefined) {
if (slot === SkillTriggerType.Field) {
const firstEntry = hero.field?.[0]?.uuids?.[0];
return firstEntry ? FieldSkillSet[firstEntry.uuid]?.icon : undefined;
}
const grouped = hero[slot] as TriggerGrouped | undefined;
if (!grouped) return undefined;
for (const key in grouped) {
const icon = resolveTriggerSkillIcon(grouped[Number(key)]?.[0], Number(key));
if (icon) return icon;
}
return undefined;
}
// 普攻/大招(slot 缺省时优先定位):lv_entries 首档 icon > 基础 overrides.icon > 底座
const hSkill = hero.skills?.[skillUuid];
if (hSkill && slot === undefined) {
return hSkill.lv_entries?.[0]?.overrides?.icon
?? hSkill.overrides?.icon
?? SkillSet[skillUuid]?.icon;
}
// 指定触发槽位:该组首个 s_uuid 首档 icon
if (slot !== undefined && slot !== SkillTriggerType.Field) {
const grouped = hero[slot] as TriggerGrouped | undefined;
const entry = grouped?.[skillUuid]?.[0];
if (entry) return resolveTriggerSkillIcon(entry, skillUuid);
return undefined;
}
// 自动定位:再各触发组,最后光环
for (const type of [SkillTriggerType.Call, SkillTriggerType.Dead, SkillTriggerType.FStart, SkillTriggerType.Atking, SkillTriggerType.Atked]) {
const grouped = hero[type] as TriggerGrouped | undefined;
const entry = grouped?.[skillUuid]?.[0];
if (entry) return resolveTriggerSkillIcon(entry, skillUuid);
}
if (hero.field?.some(t => t.uuids.some(u => u.uuid === skillUuid))) {
return FieldSkillSet[skillUuid]?.icon;
}
return undefined;
}
/** 触发技能档位图标:档位 overrides.icon 优先,缺省回退该 s_uuid 的底座 icon */
function resolveTriggerSkillIcon(entry: LvTriggerEntry | undefined, skillUuid: number): string | undefined {
if (!entry) return undefined;
return entry.overrides?.icon ?? SkillSet[skillUuid]?.icon;
}
/**
* 复活已纳入 dead 触发组:通过 SkillOverrides.revive_hp / revive_count 配置,
* 不再需要独立的 revive 字段和解析函数。
*/
/**
* 英雄/怪物基础信息接口
*/
export interface heroInfo {
uuid: number; // 唯一标识(英雄5000段,怪物5200段)
name: string; // 显示名称
icon?: string; // 图标名称(对应美术资源名)
path: string; // 资源路径(对应美术资源名)
fac: FacSet; // 阵营(FacSet.HERO 或 FacSet.MON)
kind?: number; // 未使用
lv: number; // 英雄等级
rarity?: number; // 卡牌等级(驱动 bg_node 颜色:1=green 2=blue 3=purple 4=red 5=yellow)
type: HType; // 攻击定位(近战/中程/远程)
grow_type?: HGrowType; // 成长类型(决定每级 hp/ap 标准增量,默认 Warrior)
role?: HRole; // 位置类型/职业定位(英雄专用,怪物用 monType 表达)
monType?: MonType; // 怪物专属类型
hp: number; // 生命值上限(英雄 = HERO_ROLE_BASE[role].hp + 手动增量)
ap: number; // 攻击力(英雄 = HERO_ROLE_BASE[role].ap + 手动增量)
def: number; // 防御(英雄 = HERO_ROLE_BASE[role].def + 手动增量;怪物手写,减伤走除法递减模型)
[SkillTriggerType.Call]?: TriggerGrouped; // 召唤后触发的技能配置(按 s_uuid 分组,每组按 lv 升序)
[SkillTriggerType.Dead]?: TriggerGrouped; // 死亡后触发的技能配置
[SkillTriggerType.FStart]?: TriggerGrouped; // 战斗开始时释放的技能配置
[SkillTriggerType.Field]?: LvFieldEntry[]; // 驻场光环(按 lv 升序,运行时取 ≤英雄等级 的最大档)
[SkillTriggerType.Atking]?: TriggerGrouped; // 普通攻击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的普攻次数
[SkillTriggerType.Atked]?: TriggerGrouped; // 受击后触发的技能配置,s_uuid: 技能id, t_num: 触发所需的受击次数
dis?: number; // 攻击距离(像素)
speed?: number; // 移动速度(像素/秒)
dodge?: number; // 闪避率(百分点,缺省由初始化处兜底为全局默认值)
accuracy?: number; // 命中率(百分点,缺省由初始化处兜底为全局默认值)
skills: Record<number, HSkillInfo>; // 携带技能ID列表
bonus?: LvBonusAttrsEntry[]; // 额外属性加成(按 lv 升序,运行时累加所有 lv ≤ 英雄等级 的档位 attrs;hp/ap/def 按"基础×品质+成长"快照百分比加成,crt/frz/stun/para 为固定百分点累加)
info: string; // 描述文案
/**
* @deprecated 已废弃:无任何 UI/运行时读取。技能提升说明由 HeroSkillText 依据
* 结构化配置动态生成(含数值漂移与新功能),请勿再填充此字段。
*/
infos?: string[];
}
/**
* 英雄卡配置(CHeroComp 专用,从 CardConfig 精简)
* 仅保留英雄卡渲染和交互必需的字段
*/
export interface HeroCardConfig {
uuid: number;
name?: string;
info?: string;
cost: number;
rarity: number;
base_rarity?: number;
}
/**
* 英雄卡池条目(含费用和权重,用于 MissionCardComp 抽卡)
*/
export interface HeroCardPoolEntry {
uuid: number;
cost: number;
weight: number;
rarity: number;
}
/** 英雄卡池:由 HeroList 动态生成(见文件末尾初始化代码) */
export const HeroCardPoolList: HeroCardPoolEntry[] = [];
/**
* 技能基础信息接口
*/
export interface HSkillInfo {
uuid: number; // 唯一标识(技能6000段等)
name?: string; // 对外展示的技能名(普攻/主技能);缺省时回退 SkillSet 内部名
lv: number; // 技能等级
cd: number; // 技能cd
ccd: number; // 占位当前cd,用于cd计时
overrides?: SkillOverrides; // 角色专属参数覆盖(全等级生效,作为底)
/** 技能描述模板(基础档):占位符 {target}/{dur}/{技能字段名},由 HeroSkillText 渲染合并后实时数值 */
desc?: string;
lv_entries?: LvSkillEntry[]; // 按英雄等级分档(按 lv 升序,运行时取 ≤英雄等级 的最大档)
}
/**
* 普攻技能分档配置:达到 lv 级英雄时此档 overrides 生效(与基础 overrides 浅合并,档位优先)。
* s_lv 标注此档对应的技能等级(SkillLv 枚举),便于面板显示"技能Lv.x"。
*/
export interface LvSkillEntry {
lv: number; // 达到该英雄等级时此档生效
s_lv?: SkillLv; // 此档对应的技能等级(标注用)
overrides: SkillOverrides; // 此档注入的效果
/** 此档描述模板:缺省继承上一档模板;新增机制的档位(如附加中毒)需单独配置。
* 显式配置后弹窗提升档(slv2+)直接展示该模板渲染结果,优先于自动 diff
* (护盾/治疗等 ap 含义非伤害的技能必须配置,避免 diff 标签语义错位) */
desc?: string;
}
/**
* 触发技能单档配置:达到 lv 级时此档参数生效(t_num/overrides 可随等级变化)。
* s_lv 标注此档对应的技能等级(SkillLv 枚举),表达"英雄 lv 级 → 技能 s_lv 级"的成长节奏。
*/
export interface LvTriggerEntry {
lv: number; // 达到该英雄等级时解锁此档
s_lv?: SkillLv; // 此档对应的技能等级(标注用,便于面板显示"技能Lv.x")
name?: string; // 该 s_uuid 触发技能组的对外展示名(写在第 1 档,作为组名)
t_num: number;
overrides?: SkillOverrides;
/** 此档描述模板:缺省回退该组第 1 档 desc;由 HeroSkillText 渲染合并后实时数值。
* 显式配置后弹窗提升档(slv2+)直接展示该模板渲染结果,优先于自动 diff */
desc?: string;
}
/**
* 触发技能按 s_uuid 分组的配置:每个 s_uuid 下按 lv 升序排列。
* 运行时取每个 s_uuid 中 ≤英雄等级 的最大 lv 档。
*/
export type TriggerGrouped = Record<number /*s_uuid*/, LvTriggerEntry[]>;
/**
* 驻场光环词条:uuid 指向 FieldSkillSet 底座(类型/图标/元数据),
* value 为该词条实际生效数值(由配置处按档位指定,不再随 uuid 分档)。
* name 为该词条在英雄语境下的对外展示名(写在首次出现的档位),缺省回退 FieldSkillSet 底座名。
*/
export interface FieldEntry {
uuid: number;
value: number;
name?: string; // 英雄语境对外展示名(写在该词条首次出现的档位)
}
/**
* 驻场光环按等级解锁:运行时取 ≤英雄等级 的最大 lv 档的词条列表。
*/
export interface LvFieldEntry {
lv: number;
uuids: FieldEntry[];
/** 档位描述(可选,缺省由 HeroSkillText 按 FieldDescSet 自动生成) */
desc?: string;
}
/**
* 额外属性加成按等级叠加:运行时累加所有 ≤英雄等级 的档位 attrs。
* 口径约定:hp/ap/def 为百分比(基数取"基础×品质+成长"快照,多档同键加法叠加不滚雪球);
* crt/frz/stun/para 为固定百分点(直接累加到对应概率属性)。
*/
export type BonusAttrKey = 'hp' | 'ap' | 'def' | 'crt' | 'frz' | 'stun' | 'para';
export interface LvBonusAttrsEntry {
lv: number;
attrs: Partial<Record<BonusAttrKey, number>>;
/** 展示名(图鉴技能图标/弹窗用,如「钢铁壁垒」);缺省不出图标 */
name?: string;
/** 图标帧名(gui/ui7 图集);缺省该档不在图鉴出图标 */
icon?: string;
/** 自定义描述模板(可选);缺省由 attrs 自动生成效果文案 */
info?: string;
}
/*
*=============英雄配置列表================
* 几何王国复刻版 — 依据 英雄设计指引.md(A/B 级复刻英雄)配置
*
* 规则:lv1 激活 skills[0]/skills[1],lv6 解锁 atking/atked/fstart/dead/field 触发技能(触发类统一 lv6 激活,无品质门槛),
* 大招(skills[1])lv9/lv16 走 lv_entries 分档成长,lv12 按职业对单项基础属性 +50%(基数取 lv11 有效值),
* revive[0] 与 skills[1] 互斥二选一(配置 revive 时按 lv1/lv9/lv16 走 lv_entries 3 级成长),
* 品质(rarity)仅影响 lv1 初始基础属性(相邻差 5%,仅 lv1 初始 AP/HP/DEF),不影响 uuid 段位/光环/技能解锁/属性补偿
* 编号:本批复刻英雄集中于 5001~5009,rarity 按配置(不遵循段位规则)
*/
// @hero-setup:region-begin
export const HeroInfo: Record<number, heroInfo> = {
// @hero-setup:heroes-begin
// 5001 叠甲骑士 — CSV导入:自身护盾+全体护盾
5001: {
uuid: 5001, name: "叠甲骑士", path: "hk1", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp + 20, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def + 10,
skills: {
6004: { uuid: 6004, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: {"ap":100,"timed_buff_id":7010,"buff_chance":50}, desc: "挥剑对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"ap":120}, desc: "普通攻击造成 120% 攻击伤害" },
],
},
6301: { uuid: 6301, name: "魔法盾", lv: 1, cd: 8, ccd: 0, overrides: {"ap":30}, desc: "{target}获得生命最大值{ap}%的护盾",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":60}, desc: "{target}获得生命最大值{ap}%的护盾" },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":120}, desc: "{target}获得生命最大值{ap}%的护盾" },
],
},
},
atked: {
6301: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "全体圣盾", t_num: 3, overrides: {"TGroup":null,"ap":10,"icon":"Stat_UnitSummonIncrease_01"}, desc: "全队获得本英雄生命最大值{ap}%的护盾" },
],
},
bonus: [
{ lv: 12, attrs: {"def":50}, name: "钢铁壁垒", icon: "46-Iron-Clad", },
],
info: "自身强护盾+群体小护盾,强生存",
},
// 5002 易伤剑仙 — CSV导入:击退压场+易伤放大;复刻酒仙
5002: {
uuid: 5002, name: "易伤剑仙", path: "hk3", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, hp: HERO_ROLE_BASE[HRole.Warrior].hp + 5, ap: HERO_ROLE_BASE[HRole.Warrior].ap + 20, def: HERO_ROLE_BASE[HRole.Warrior].def + 5,
skills: {
6004: { uuid: 6004, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: {"ap":100}, desc: "对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"ap":120}, desc: "普通攻击造成 120% 攻击伤害" },
],
},
6101: { uuid: 6101, name: "气斩", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150,"timed_buff_id":7002,"icon":"Stat_AttackSpeed_02"}, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,并使目标易伤(受到伤害加深,持续{dur}秒)",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"buff_value":20} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":180,"bck":60,"buff_value":40}, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,击退{bck},并使目标易伤(持续{dur}秒)" },
],
},
},
atking: {
6004: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "风暴打击", t_num: 3, overrides: {"ap":300,"icon":"Stat_AllUnitAttack"}, desc: "立刻打击{target},造成攻击力{ap}%伤害" },
],
},
bonus: [
{ lv: 12, attrs: {"hp":50}, name: "不屈战意", icon: "29-Endure", },
],
info: "易伤+风怒,近战 dps",
},
// 5003 眩晕暴击哥 — CSV导入:高爆发+击晕收割;复刻齐天大圣
5003: {
uuid: 5003, name: "眩晕暴击哥", path: "hk5", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, hp: HERO_ROLE_BASE[HRole.Warrior].hp + 5, ap: HERO_ROLE_BASE[HRole.Warrior].ap + 20, def: HERO_ROLE_BASE[HRole.Warrior].def + 5,
skills: {
6004: { uuid: 6004, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: {"ap":100}, desc: "挥斧对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"stun":10}, desc: "普通攻击有{stun}%概率击晕敌人" },
],
},
6104: { uuid: 6104, name: "开山斧", lv: 1, cd: 8, ccd: 0, overrides: {"ap":300,"stun":100}, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,必定击晕",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":450,"stun":100} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":450,"stun":100} },
],
},
},
field: [
{ lv: 4, uuids: [{ uuid: 7005, value: 0.25, name: "大圣神威" }] },
],
bonus: [
{ lv: 12, attrs: {"hp":50}, name: "不屈战意", icon: "29-Endure", },
],
info: "必晕爆发+暴击光环,近战收割",
},
// 5004 刀刀暴击 — CSV导入:暴击/暴伤双光环乘区;复刻剑圣
5004: {
uuid: 5004, name: "刀刀暴击", path: "hc1", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Mid, grow_type: HGrowType.Assassin, role: HRole.Assassin, hp: HERO_ROLE_BASE[HRole.Assassin].hp, ap: HERO_ROLE_BASE[HRole.Assassin].ap + 30, def: HERO_ROLE_BASE[HRole.Assassin].def,
skills: {
6002: { uuid: 6002, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast].cd, ccd: 0, overrides: {"ap":100}, desc: "挥刀对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"crt":10}, desc: "普通攻击有{crt}%概率暴击" },
],
},
6100: { uuid: 6100, name: "光闪", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150}, desc: "斩出光闪,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350} },
],
},
},
field: [
{ lv: 4, uuids: [{ uuid: 7004, value: 0.12, name: "剑刃风暴" }, { uuid: 7005, value: 0.2, name: "斩魂利刃" }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "致命本能", icon: "36-Guardian-Stance", },
],
info: "暴击+暴伤双光环,暴击流刺客",
},
// 5005 出血贼 — CSV导入:入场先手+受击格挡;复刻剑豪
5005: {
uuid: 5005, name: "出血贼", path: "hc2", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Mid, grow_type: HGrowType.Assassin, role: HRole.Assassin, hp: HERO_ROLE_BASE[HRole.Assassin].hp, ap: HERO_ROLE_BASE[HRole.Assassin].ap + 30, def: HERO_ROLE_BASE[HRole.Assassin].def,
skills: {
6002: { uuid: 6002, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast].cd, ccd: 0, overrides: {"ap":100}, desc: "挥刀对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"timed_buff_id":7007,"buff_value":30,"buff_chance":30}, desc: "普通攻击有{buff_chance}%概率使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
],
},
6103: { uuid: 6103, name: "闪电斩", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150}, desc: "高速斩击{target},造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250,"timed_buff_id":7007,"buff_value":40}, desc: "高速斩击{target},造成攻击力{ap}%,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350,"timed_buff_id":7007,"buff_value":60}, desc: "高速斩击{target},造成攻击力{ap}%,附带 50% 概率麻痹,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
],
},
},
field: [
{ lv: 4, uuids: [{ uuid: 7002, value: 10, name: "攻击光环" }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "致命本能", icon: "36-Guardian-Stance", },
],
info: "普攻出血+大招群体出血,持续消耗",
},
// 5006 冻箭哥 — CSV导入:多重单体箭,带冰冻
5006: {
uuid: 5006, name: "冻箭哥", path: "ha1", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Archer, role: HRole.Archer, hp: HERO_ROLE_BASE[HRole.Archer].hp, ap: HERO_ROLE_BASE[HRole.Archer].ap + 30, def: HERO_ROLE_BASE[HRole.Archer].def,
skills: {
6006: { uuid: 6006, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0, overrides: {"ap":100}, desc: "射出箭矢,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"frz":10}, desc: "普通攻击有{frz}%概率 冰冻敌人" },
],
},
6150: { uuid: 6150, name: "万箭齐发·冰", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150,"frz":30,"icon":"Stat_AttackRangeIncrease_02"}, desc: "万箭齐发,对{target}造成攻击力{ap}%伤害,{frz}%概率冰冻",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":200,"frz":50} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":250,"frz":70} },
],
},
},
field: [
{ lv: 4, uuids: [{ uuid: 7006, value: 0.15 }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "鹰眼锁定", icon: "27-Hawkeye", },
],
info: "冰冻控场+多重箭,远程控制",
},
// 5007 击退火女 — CSV导入:群体击退/麻痹压场;复刻深渊女王
5007: {
uuid: 5007, name: "击退火女", path: "hm1", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: HERO_ROLE_BASE[HRole.Mage].hp - 5, ap: HERO_ROLE_BASE[HRole.Mage].ap + 10, def: HERO_ROLE_BASE[HRole.Mage].def,
skills: {
6010: { uuid: 6010, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: {"ap":100}, desc: "掷出紫魔球,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"bck_chance":20}, desc: "普通攻击有{bck_chance}%概率击退敌人" },
],
},
6200: { uuid: 6200, name: "火焰喷射", lv: 1, cd: 8, ccd: 0, overrides: {"ap":250,"bck":100}, desc: "喷出烈焰风暴,对{target}造成攻击力{ap}%伤害,击退{bck}",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":350,"bck":100} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":450,"bck":100,"summon_count":2} },
],
},
},
field: [
{ lv: 4, uuids: [{ uuid: 7002, value: 0.15, name: "深渊威压" }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "奥术共鸣", icon: "100-Enchant-Magic", },
],
info: "烈焰击退+易伤光环,法系压场",
},
// 5008 团疗奶爸 — CSV导入:全体治疗续航+自身护盾
5008: {
uuid: 5008, name: "团疗奶爸", path: "hh1", fac: FacSet.HERO, rarity: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Support, role: HRole.Support, hp: HERO_ROLE_BASE[HRole.Support].hp + 10, ap: HERO_ROLE_BASE[HRole.Support].ap + 20, def: HERO_ROLE_BASE[HRole.Support].def,
skills: {
6011: { uuid: 6011, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0, overrides: {"ap":100}, desc: "挥杖对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"ap":120}, desc: "普通攻击造成 120% 攻击伤害" },
],
},
6302: { uuid: 6302, name: "治疗", lv: 1, cd: 8, ccd: 0, overrides: {"ap":30}, desc: "为{target}回复攻击力{ap}%生命",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":40} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":50} },
],
},
},
atking: {
6301: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "圣愈之盾", t_num: 3, overrides: {"ap":30}, desc: "{target}获得生命最大值{ap}%的护盾" },
],
},
bonus: [
{ lv: 12, attrs: {"hp":50}, name: "守护之心", icon: "29-Endure", },
],
info: "全体治疗+攻击附盾,团队续航",
},
// 5009 甲虫领主
5009: {
uuid: 5009, name: "甲虫领主", path: "hk2", fac: FacSet.HERO, rarity: 2, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def,
skills: {
6004: { uuid: 6004, name: "普攻强化", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0,
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"proc_skill":{"s_uuid":6502,"chance":10,"overrides":{"ap":5,"TGroup": TGroup.Self}}}, desc: "普通攻击有 10% 的概率为自己释放回春(5 秒恢复生命值的{ap}%)" },
],
},
6102: { uuid: 6102, lv: 1, cd: 8, ccd: 0, overrides: {"ap":250,"bck":30},
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":300,"bck":50} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350,"bck":70} },
],
},
},
atked: {
6302: [
{ lv: 4, s_lv: SkillLv.Lv1, t_num: 3, overrides: {"ap":5}, desc: "为自己释放治疗,恢复生命值的{ap}%" },
],
},
bonus: [
{ lv: 12, attrs: {"def":50}, name: "钢铁壁垒", icon: "46-Iron-Clad", },
],
info: "受击自疗+击退,自愈坦克",
},
// 5010 火箭哥
5010: {
uuid: 5010, name: "火箭哥", path: "ha2", fac: FacSet.HERO, rarity: 3, lv: 1, type: HType.Mid, grow_type: HGrowType.Archer, role: HRole.Archer, hp: HERO_ROLE_BASE[HRole.Archer].hp, ap: HERO_ROLE_BASE[HRole.Archer].ap, def: HERO_ROLE_BASE[HRole.Archer].def,
skills: {
6006: { uuid: 6006, name: "强化普攻", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast].cd, ccd: 0,
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"ap":100,"bck_chance":10} },
],
},
6151: { uuid: 6151, lv: 1, cd: 8, ccd: 0, overrides: {"ap":70,"summon_count":5,"bck_chance":100},
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":80,"summon_count":5,"bck_chance":100} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"bck_chance":100,"ap":100,"summon_count":6} },
],
},
},
atking: {
6008: [
{ lv: 4, s_lv: SkillLv.Lv1, t_num: 3, overrides: {"ap":120,"bck_chance":50} },
],
},
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "鹰眼锁定", icon: "27-Hawkeye", },
],
info: "万箭齐射+高频击退,远程压制",
},
// 5011 控血大师
5011: {
uuid: 5011, name: "控血大师", path: "hk3", fac: FacSet.HERO, rarity: 4, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def,
skills: {
6004: { uuid: 6004, name: "普攻强化", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0,
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"proc_skill":{"s_uuid":6502,"chance":10,"overrides":{"ap":5}}}, desc: "普攻有 10% 概率,对自己释放回春(5 秒回复5% 生命)" },
],
},
6517: { uuid: 6517, name: "生命爆发", lv: 1, cd: 8, ccd: 0, overrides: {"buff_value":30,"buff_duration":10}, desc: "全体友方最大生命值提升{buff_value}%,持续{dur}秒",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"buff_value":40,"buff_duration":10}, desc: "全体友方最大生命值提升{buff_value}%,持续{dur}秒" },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"buff_value":50,"buff_duration":15}, desc: "全体友方最大生命值提升{buff_value}%,持续{dur}秒" },
],
},
},
atked: {
6402: [
{ lv: 4, s_lv: SkillLv.Lv1, t_num: 5, overrides: {"ap":1,"TGroup": TGroup.Ally,"hit_count":3}, desc: "全队永久增加 1% 生命最大值" },
],
},
bonus: [
{ lv: 12, attrs: {"def":50}, name: "钢铁壁垒", icon: "46-Iron-Clad", },
],
info: "永久和计时生命最大值,控血大师",
},
// 5012 疾风法师
5012: {
uuid: 5012, name: "疾风法师", path: "hm2", fac: FacSet.HERO, rarity: 5, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: HERO_ROLE_BASE[HRole.Mage].hp, ap: HERO_ROLE_BASE[HRole.Mage].ap, def: HERO_ROLE_BASE[HRole.Mage].def,
skills: {
6009: { uuid: 6009, name: "普攻强化", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0,
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"proc_skill":{"s_uuid":6507,"chance":10,"overrides":{"buff_value":30,"TGroup": TGroup.Self}}} },
],
},
6201: { uuid: 6201, name: "飓风", lv: 1, cd: 8, ccd: 0, overrides: {"ap":100,"summon_count":2,"proc_skill":{"s_uuid":6507,"chance":20,"overrides":{"buff_value":20}}}, desc: "召唤 {summon_count} 道飓风攻击前方敌人,每道飓风造成 {ap}%伤害,每道飓风释放时有<color=#3CE66E>20</color>% 概率增加全体队友<color=#3CE66E>20</color>% 攻速",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":100,"summon_count":3,"proc_skill":{"s_uuid":6507,"chance":20,"overrides":{"buff_value":20}}}, desc: "召唤 {summon_count} 道飓风攻击前方敌人,每道飓风造成 {ap}%伤害,每道飓风释放时有<color=#3CE66E>20</color>% 概率增加全体队友<color=#3CE66E>20</color>% 攻速" },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":100,"summon_count":4,"proc_skill":{"s_uuid":6507,"chance":20,"overrides":{"buff_value":20}}}, desc: "召唤 {summon_count} 道飓风攻击前方敌人,每道飓风造成 {ap}%伤害,每道飓风释放时有<color=#3CE66E>20</color>% 概率增加全体队友<color=#3CE66E>20</color>% 攻速" },
],
},
},
field: [
{ lv: 4, uuids: [{ uuid: 7006, value: 10 }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "奥术共鸣", icon: "100-Enchant-Magic", },
],
info: "普攻 大招加速 buff+加速光环,加速大师",
},
// 5013 反伤哥
5013: {
uuid: 5013, name: "反伤哥", path: "hh2", fac: FacSet.HERO, rarity: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Support, role: HRole.Support, hp: HERO_ROLE_BASE[HRole.Support].hp, ap: HERO_ROLE_BASE[HRole.Support].ap, def: HERO_ROLE_BASE[HRole.Support].def,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0,
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"timed_buff_id":7029,"buff_value":10,"buff_chance":20} },
],
},
6515: { uuid: 6515, name: "荆棘护盾", lv: 1, cd: 8, ccd: 0, overrides: {"buff_value":20,"TGroup": TGroup.Ally,"hit_count":3,"buff_duration":5},
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"buff_value":25,"TGroup": TGroup.Ally,"hit_count":3,"buff_duration":10} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"buff_value":30,"buff_duration":10,"hit_count":3,"TGroup": TGroup.Ally} },
],
},
},
fstart: {
6301: [
{ lv: 4, s_lv: SkillLv.Lv1, t_num: 1, overrides: {"ap":20} },
],
},
bonus: [
{ lv: 12, attrs: {"hp":50}, name: "守护之心", icon: "29-Endure", },
],
info: "大招全体反伤 普攻暴击 暴击反伤辅助",
},
// 5014 闪避哥
5014: {
uuid: 5014, name: "闪避哥", path: "hk4", fac: FacSet.HERO, rarity: 4, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, hp: HERO_ROLE_BASE[HRole.Warrior].hp, ap: HERO_ROLE_BASE[HRole.Warrior].ap, def: HERO_ROLE_BASE[HRole.Warrior].def,
skills: {
6004: { uuid: 6004, name: "普攻强化", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0,
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"timed_buff_id":7030,"buff_value":10,"buff_chance":20} },
],
},
6100: { uuid: 6100, name: "寒冰斩", lv: 1, cd: 8, ccd: 0, overrides: {"ap":200,"timed_buff_id":7030,"buff_value":50},
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250,"timed_buff_id":7030,"buff_value":50} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":350,"timed_buff_id":7030,"buff_value":80} },
],
},
},
field: [
{ lv: 4, uuids: [{ uuid: 7023, value: 10 }] },
],
bonus: [
{ lv: 12, attrs: {"hp":50}, name: "不屈战意", icon: "29-Endure", },
],
info: "",
},
// 5015 毒箭猎手 — 毒伤持续流:普攻淬毒叠层+毒雨铺DoT+攻击光环喂养毒伤
5015: {
uuid: 5015, name: "毒箭猎手", path: "ha3", fac: FacSet.HERO, rarity: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Archer, role: HRole.Archer, hp: HERO_ROLE_BASE[HRole.Archer].hp + 10, ap: HERO_ROLE_BASE[HRole.Archer].ap, def: HERO_ROLE_BASE[HRole.Archer].def,
skills: {
6007: { uuid: 6007, name: "淬毒箭", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0, overrides: {"ap":100}, desc: "射出箭矢,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"timed_buff_id":7005,"buff_value":30,"buff_chance":30}, desc: "普通攻击有{buff_chance}%概率使目标中毒(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
],
},
6150: { uuid: 6150, name: "万箭齐发·毒", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150,"timed_buff_id":7005,"buff_value":30,"buff_chance":50,"icon":"4-Apply-Poison"}, desc: "毒箭如雨,对{target}造成攻击力{ap}%伤害,{buff_chance}%概率使目标中毒(每0.5秒受到{buff_value}点伤害,持续{dur}秒)",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":200,"buff_value":40,"buff_chance":60} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":250,"buff_value":60,"buff_chance":80,"hit_count":2}, desc: "毒箭如雨,对{target}造成攻击力{ap}%伤害,{buff_chance}%概率使目标中毒(每0.5秒受到{buff_value}点伤害,持续{dur}秒),每支箭可命中{hit_count}个目标" },
],
},
},
atking: {
6007: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "蚀骨毒箭", t_num: 3, overrides: {"ap":80,"timed_buff_id":7005,"buff_value":40,"buff_chance":100}, desc: "追加射出蚀骨毒箭,对{target}造成攻击力{ap}%伤害,必定使目标中毒(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
],
},
field: [
{ lv: 4, uuids: [{ uuid: 7002, value: 0.1, name: "淬毒磨砺" }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "剧毒淬炼", icon: "27-Hawkeye", },
],
info: "淬毒普攻+毒雨叠层,持续消耗型远程毒C",
},
// 5016 连珠神射 — 暴击连射爆发流:VeryFast极速普攻+概率追射必暴箭+开局团队暴击爆发
5016: {
uuid: 5016, name: "连珠神射", path: "ha4", fac: FacSet.HERO, rarity: 4, lv: 1, type: HType.Mid, grow_type: HGrowType.Archer, role: HRole.Archer, hp: HERO_ROLE_BASE[HRole.Archer].hp, ap: HERO_ROLE_BASE[HRole.Archer].ap + 10, def: HERO_ROLE_BASE[HRole.Archer].def,
skills: {
6008: { uuid: 6008, name: "连珠箭", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VeryFast].cd, ccd: 0, overrides: {"ap":100}, desc: "极速连射,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"crt":20,"proc_skill":{"s_uuid":6007,"chance":20,"overrides":{"crt":100}}}, desc: "普通攻击暴击率提升{crt}%,并有概率触发连射追箭(必定暴击)" },
],
},
6151: { uuid: 6151, name: "裂空箭雨", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150,"crt":30,"summon_count":5}, desc: "箭雨倾泻,对{target}造成攻击力{ap}%伤害,{crt}%概率暴击",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":200,"crt":50} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":250,"crt":70,"summon_count":6,"hit_count":2}, desc: "箭雨倾泻,对{target}造成攻击力{ap}%伤害,{crt}%概率暴击,每支箭可命中{hit_count}个目标" },
],
},
},
fstart: {
6504: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "猎杀时刻", t_num: 1, overrides: {"buff_value":30}, desc: "战斗开始时释放暴击爆发,全体友方暴击率提升{buff_value}%,持续{dur}秒" },
],
},
field: [
{ lv: 4, uuids: [{ uuid: 7004, value: 0.15, name: "猎手集结" }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "猎杀直觉", icon: "27-Hawkeye", },
],
info: "极速连射+暴击追射+开局团队暴击,爆发型射手主C",
},
// 5017 碎甲术士 — 破甲减防法师:fstart先手/普攻概率/大招必定三通道施加破甲7008+穿透光环,团队物理增伤位
5017: {
uuid: 5017, name: "碎甲术士", path: "hm3", fac: FacSet.HERO, rarity: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: HERO_ROLE_BASE[HRole.Mage].hp, ap: HERO_ROLE_BASE[HRole.Mage].ap + 10, def: HERO_ROLE_BASE[HRole.Mage].def,
skills: {
6012: { uuid: 6012, name: "蚀甲酸瓶", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0, overrides: {"ap":100}, desc: "掷出酸瓶,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"timed_buff_id":7008,"buff_chance":30}, desc: "普通攻击有{buff_chance}%概率使目标破甲(防御降低,持续{dur}秒)" },
],
},
6203: { uuid: 6203, name: "碎甲能量波", lv: 1, cd: 8, ccd: 0, overrides: {"ap":150,"timed_buff_id":7008}, desc: "释放碎甲能量波,对{target}造成攻击力{ap}%伤害,并使目标破甲(防御降低,持续{dur}秒)",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":200} },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":250,"buff_value":-70}, desc: "释放碎甲能量波,对{target}造成攻击力{ap}%伤害,并使目标破甲加深(防御大幅降低,持续{dur}秒)" },
],
},
},
fstart: {
6012: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "先手蚀甲", t_num: 1, overrides: {"ap":150,"timed_buff_id":7008}, desc: "战斗开始时掷出蚀甲酸瓶,对{target}造成攻击力{ap}%伤害,并必定使其破甲(防御降低,持续{dur}秒)" },
],
},
field: [
{ lv: 4, uuids: [{ uuid: 7009, value: 0.1, name: "锐矛之赐" }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "奥术共鸣", icon: "100-Enchant-Magic", },
],
info: "先手破甲+概率蚀甲+穿透光环,物理队核心增伤位",
},
// 5018 雷暴领主 — 雷暴AOE爆发+麻痹控场:先手雷击+高倍率能量波
5018: {
uuid: 5018, name: "雷暴领主", path: "hm4", fac: FacSet.HERO, rarity: 5, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: HERO_ROLE_BASE[HRole.Mage].hp - 10, ap: HERO_ROLE_BASE[HRole.Mage].ap + 20, def: HERO_ROLE_BASE[HRole.Mage].def,
skills: {
6009: { uuid: 6009, name: "雷霆弹", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast].cd, ccd: 0, overrides: {"ap":100}, desc: "掷出雷霆弹,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"para":15}, desc: "普通攻击有{para}%概率麻痹敌人,减缓其技能冷却恢复" },
],
},
6203: { uuid: 6203, name: "雷霆裂空", lv: 1, cd: 8, ccd: 0, overrides: {"ap":200,"para":40}, desc: "释放雷霆裂空波,对{target}造成攻击力{ap}%伤害,{para}%概率麻痹敌人",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":250,"para":60}, desc: "释放雷霆裂空波,对{target}造成攻击力{ap}%伤害,{para}%概率麻痹敌人" },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":300,"para":80,"hit_count":3}, desc: "释放雷霆裂空波,对{target}造成攻击力{ap}%伤害,可多次命中,{para}%概率麻痹敌人" },
],
},
},
fstart: {
6203: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "雷击先手", t_num: 1, overrides: {"ap":150,"para":30,"icon":"100-Enchant-Magic"}, desc: "战斗开始释放雷击,对{target}造成攻击力{ap}%伤害,{para}%概率麻痹敌人" },
],
},
field: [
{ lv: 4, uuids: [{ uuid: 7003, value: 10, name: "雷云领域" }] },
],
bonus: [
{ lv: 12, attrs: {"ap":50}, name: "奥术共鸣", icon: "100-Enchant-Magic", },
],
info: "雷暴爆发+麻痹控场,法系主C",
},
// 5019 圣盾贤者 — 护盾反伤生存法:全队圣盾+荆棘反伤+受击荆棘
5019: {
uuid: 5019, name: "圣盾贤者", path: "hm5", fac: FacSet.HERO, rarity: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, hp: HERO_ROLE_BASE[HRole.Mage].hp + 20, ap: HERO_ROLE_BASE[HRole.Mage].ap - 5, def: HERO_ROLE_BASE[HRole.Mage].def + 5,
skills: {
6011: { uuid: 6011, name: "圣光飞瓶", lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0, overrides: {"ap":100}, desc: "掷出圣光飞瓶,对{target}造成攻击力{ap}%伤害",
lv_entries: [
{ lv: 2, s_lv: SkillLv.Lv2, overrides: {"proc_skill":{"s_uuid":6516,"chance":20,"overrides":{"timed_buff_id":7028,"buff_value":10}}}, desc: "普通攻击概率凝聚荆棘护体(受击时反弹{buff_value}%所受伤害,持续{dur}秒)" },
],
},
6301: { uuid: 6301, name: "奥术圣壁", lv: 1, cd: 8, ccd: 0, overrides: {"TGroup": TGroup.Ally,"ap":20,"timed_buff_id":7027,"buff_value":10}, desc: "为全体友方施加生命最大值{ap}%的护盾,并附加荆棘(受击时反弹{buff_value}点伤害,持续{dur}秒)",
lv_entries: [
{ lv: 8, s_lv: SkillLv.Lv2, overrides: {"ap":30,"buff_value":15}, desc: "为全体友方施加生命最大值{ap}%的护盾,并附加荆棘(受击时反弹{buff_value}点伤害,持续{dur}秒)" },
{ lv: 16, s_lv: SkillLv.Lv3, overrides: {"ap":40,"buff_value":20}, desc: "为全体友方施加生命最大值{ap}%的护盾,并附加荆棘(受击时反弹{buff_value}点伤害,持续{dur}秒)" },
],
},
},
atked: {
6516: [
{ lv: 4, s_lv: SkillLv.Lv1, name: "荆棘回应", t_num: 3, overrides: {"timed_buff_id":7028,"buff_value":10,"icon":"75-Shield-Stun"}, desc: "凝聚荆棘护体,受击时反弹{buff_value}%所受伤害,持续{dur}秒" },
],
},
field: [
{ lv: 4, uuids: [{ uuid: 7022, value: 8, name: "荆棘领域" }] },
],
bonus: [
{ lv: 12, attrs: {"hp":50}, name: "守护之心", icon: "29-Endure", },
],
info: "全队护盾+荆棘反伤,生存反击法",
},
// @hero-setup:heroes-end
/*
*=============怪物配置列表================
* 怪物与英雄采用同一套设定体系:基础值 = HERO_ROLE_BASE[role],品质(rarity)
* 相邻基础属性差 5%,成长系数走 HERO_GROW_COEF[grow_type]。
* 怪物普攻统一使用 SkillSet 基础单体攻击(6001~6012 段),
* 并通过 overrides.ap=100 显式声明伤害为攻击力的 100%。
* 怪物按等级成长由后续肉鸽配置驱动,当前配置承担"职业基准 + 品质差异"的静态表达。
*/
// 基础怪物 (全部固定点位站桩攻击,HType仅决定是前排还是后排)
// 前排怪物 — 战士系基准(Warrior 模板),变体按品质微分定位
6001: {
uuid: 6001, name: "兽人战士", path: "m1", fac: FacSet.MON, lv: 1, rarity: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, monType: MonType.Melee, hp: HERO_ROLE_BASE[HRole.Warrior].hp, ap: HERO_ROLE_BASE[HRole.Warrior].ap, def: HERO_ROLE_BASE[HRole.Warrior].def, speed: 70,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "基础前排怪, 战士系基准"
},
6002: {
uuid: 6002, name: "兽人精锐战士", path: "m2", fac: FacSet.MON, lv: 1, rarity: 2, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, monType: MonType.Melee, hp: HERO_ROLE_BASE[HRole.Warrior].hp, ap: HERO_ROLE_BASE[HRole.Warrior].ap, def: HERO_ROLE_BASE[HRole.Warrior].def, speed: 110,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } }, info: "进阶前排怪, 品质2更快更痛"
},
6003: {
uuid: 6003, name: "兽人重装兵", path: "m3", fac: FacSet.MON, lv: 1, rarity: 2, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, monType: MonType.Heavy, hp: HERO_ROLE_BASE[HRole.Tank].hp, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def, speed: 50,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "重型坦克怪, 高HP低攻承伤位"
},
// 后排怪物 — 射手/刺客/法系基准,变体按品质微分定位
6004: {
uuid: 6004, name: "兽人射手", path: "m4", fac: FacSet.MON, lv: 1, rarity: 1, type: HType.Long, grow_type: HGrowType.Archer, role: HRole.Archer, monType: MonType.Long, hp: HERO_ROLE_BASE[HRole.Archer].hp, ap: HERO_ROLE_BASE[HRole.Archer].ap, def: HERO_ROLE_BASE[HRole.Archer].def, speed: 70,
skills: { 6006: { uuid: 6006, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "后排输出怪, 射手系基准"
},
6005: {
uuid: 6005, name: "兽人刺客", path: "m5", fac: FacSet.MON, lv: 1, rarity: 1, type: HType.Long, grow_type: HGrowType.Assassin, role: HRole.Assassin, monType: MonType.Assassin, hp: HERO_ROLE_BASE[HRole.Assassin].hp, ap: HERO_ROLE_BASE[HRole.Assassin].ap, def: HERO_ROLE_BASE[HRole.Assassin].def, speed: 130,
skills: { 6002: { uuid: 6002, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0, overrides: { ap: 100, hit_count: 2 } } }, info: "高攻速低HP刺客"
},
// 特殊位怪物
6006: {
uuid: 6006, name: "骷髅领主", path: "m6", fac: FacSet.MON, lv: 1, rarity: 3, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, monType: MonType.MeleeBoss, hp: HERO_ROLE_BASE[HRole.Tank].hp, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def, speed: 60,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "前排MiniBoss级坦克"
},
6007: {
uuid: 6007, name: "兽人术士", path: "m7", fac: FacSet.MON, lv: 1, rarity: 1, type: HType.Long, grow_type: HGrowType.Support, role: HRole.Support, monType: MonType.Support, hp: HERO_ROLE_BASE[HRole.Support].hp, ap: HERO_ROLE_BASE[HRole.Support].ap, def: HERO_ROLE_BASE[HRole.Support].def, speed: 70,
skills: { 6009: { uuid: 6009, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, hit_count: 2 } } }, info: "后排辅助法师怪"
},
6008: {
uuid: 6008, name: "兽人火法", path: "m8", fac: FacSet.MON, lv: 1, rarity: 1, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, monType: MonType.Summoner, hp: HERO_ROLE_BASE[HRole.Mage].hp, ap: HERO_ROLE_BASE[HRole.Mage].ap, def: HERO_ROLE_BASE[HRole.Mage].def, speed: 70,
skills: { 6010: { uuid: 6010, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, hit_count: 2 } } }, info: "后排召唤系法师怪"
},
// BOSS怪物 — 与英雄同一套设定(role 模板 + 品质系数),高品质承伤/输出位
6101: {
uuid: 6101, name: "兽人首领-双刀战士", path: "mb1", fac: FacSet.MON, lv: 6, rarity: 4, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, monType: MonType.MeleeBoss, hp: HERO_ROLE_BASE[HRole.Warrior].hp, ap: HERO_ROLE_BASE[HRole.Warrior].ap, def: HERO_ROLE_BASE[HRole.Warrior].def, speed: 120,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "前排Boss, 攻速型"
},
6102: {
uuid: 6102, name: "兽人首领-斧头战士", path: "mb2", fac: FacSet.MON, lv: 6, rarity: 5, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, monType: MonType.MeleeBoss, hp: HERO_ROLE_BASE[HRole.Tank].hp, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def, speed: 60,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "前排Boss, 超高HP"
},
6103: {
uuid: 6103, name: "兽人首领-魔法师", path: "mb3", fac: FacSet.MON, lv: 6, rarity: 4, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, monType: MonType.LongBoss, hp: HERO_ROLE_BASE[HRole.Mage].hp, ap: HERO_ROLE_BASE[HRole.Mage].ap, def: HERO_ROLE_BASE[HRole.Mage].def, speed: 110,
skills: { 6009: { uuid: 6009, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, hit_count: 2 } } }, info: "后排法系Boss"
},
6104: {
uuid: 6104, name: "兽人首领-射手", path: "mb4", fac: FacSet.MON, lv: 6, rarity: 4, type: HType.Long, grow_type: HGrowType.Archer, role: HRole.Archer, monType: MonType.LongBoss, hp: HERO_ROLE_BASE[HRole.Archer].hp, ap: HERO_ROLE_BASE[HRole.Archer].ap, def: HERO_ROLE_BASE[HRole.Archer].def, speed: 70,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "后排位Boss, 均衡型"
},
6105: {
uuid: 6105, name: "亡灵首领-法师", path: "mb5", fac: FacSet.MON, lv: 6, rarity: 5, type: HType.Long, grow_type: HGrowType.Mage, role: HRole.Mage, monType: MonType.LongBoss, hp: HERO_ROLE_BASE[HRole.Mage].hp, ap: HERO_ROLE_BASE[HRole.Mage].ap, def: HERO_ROLE_BASE[HRole.Mage].def, speed: 110,
skills: { 6011: { uuid: 6011, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, hit_count: 2, timed_buff_id: 7002 } } }, info: "后排高AP Boss"
},
6106: {
uuid: 6106, name: "亡灵首领-骑马战士", path: "mb6", fac: FacSet.MON, lv: 6, rarity: 5, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, monType: MonType.MeleeBoss, hp: HERO_ROLE_BASE[HRole.Tank].hp, ap: HERO_ROLE_BASE[HRole.Tank].ap, def: HERO_ROLE_BASE[HRole.Tank].def, speed: 130,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "前排终极Boss, 最高HP+高速"
},
};
export const HeroList: number[] = [
// 编辑器导出自动同步(共 19 个)
5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010,
5011, 5012, 5013, 5014, 5015, 5016, 5017, 5018, 5019,
];
// @hero-setup:region-end
// ==================== 英雄推荐阵容配置 ====================
/**
* 推荐阵容条目。
* Why: 场上固定 3 个英雄(FightSet.HERO_FIELD_NUM),围绕"发动机 → 增益 → 主C"铁三角结构
* 预置官方配合组合,供抽卡引导、阵容推荐 UI 与 AI 自动布阵消费。
*/
export interface HeroComboInfo {
uuid: number; // 阵容唯一标识(8000 段)
name: string; // 阵容名称(体现流派)
heroes: number[]; // 英雄 uuid 列表,固定 3 个;索引 0=前排,其余按站位从近到远
desc: string; // 配合思路说明(信息面板展示)
low_heroes?: number[]; // 低配替代阵容(rarity 1~2,供新手期引导)
}
/**
* 推荐阵容表(几何王国复刻版 5001~5009)。
* 设计原则:
* 1. 铁三角结构:1 前排(坦克)+ 1 增益(光环/先手)+ 1 主C
* 2. 乘区分散:攻击/暴击/暴伤各占独立乘区,组合优先覆盖不同乘区避免稀释
* 3. 发动机冗余:前排挨打/死亡触发增益,叠甲骑士(5005)死亡缠绕负责献祭点火
*/
export const HeroComboSet: Record<number, HeroComboInfo> = {
// 8001 暴击爆发流 — 暴击率与暴伤双乘区互不稀释,成型最强
8001: {
uuid: 8001, name: "暴击爆发流",
heroes: [5005, 5008, 5002],
desc: "叠甲骑士前排抗伤叠甲,刀刀暴击的暴击光环与眩晕暴击哥的暴伤光环组成双乘区,双近战暴击爆发收割。",
},
// 8002 冰雷控制流 — 冰冻+击晕双控场,敌人出不了手
8002: {
uuid: 8002, name: "冰雷控制流",
heroes: [5007, 5004, 5001],
desc: "微醺战神前排击退压场,冻住不谢冰冻链配合紫电魔女能量波击退击晕,击晕光环叠加,全场控制。",
},
// 8003 铁桶续航流 — 双防御前排+双治疗保血,最稳
8003: {
uuid: 8003, name: "铁桶续航流",
heroes: [5005, 5009, 5006],
desc: "叠甲骑士与铁壳斧弟双前排叠甲叠防,光明奶爸治疗+生命光环抬全队血线,专打持久消耗战。",
},
// 8004 先手爆发流 — 入场剑气先手+能量波跟进,短回合最强
8004: {
uuid: 8004, name: "先手爆发流",
heroes: [5003, 5001, 5008],
desc: "格挡反杀入场500%剑气先手压血线,紫电魔女能量波击退跟进,眩晕暴击哥开山斧收割残局。",
},
// 8005 破甲推进流 — 易伤放大全队伤害,克制高血Boss
8005: {
uuid: 8005, name: "破甲推进流",
heroes: [5007, 5006, 5002],
desc: "微醺战神气斩易伤放大全队伤害,光明奶爸治疗保前排,刀刀暴击吃满易伤与自身暴击完成推进。",
},
// 8006 光环覆盖流 — 攻击/暴击/暴伤/生命光环全覆盖
8006: {
uuid: 8006, name: "光环覆盖流",
heroes: [5002, 5006, 5001],
desc: "刀刀暴击暴击+暴伤双光环、紫电魔女攻击光环、光明奶爸生命光环,四光环全覆盖持续放大全队输出。",
},
};
/** 推荐阵容 id 列表(按品质/成型难度排序,供 UI 顺序展示) */
export const HeroComboList: number[] = [8001, 8002, 8003, 8004, 8005, 8006];
// ==================== 英雄卡池初始化(必须在 HeroList 定义之后执行) ====================
/**
* 英雄卡费用规则
* lv1=5, lv2=10, lv3+=15
*/
function getHeroCost(rarity: number): number {
if (rarity === 1) return 5;
if (rarity === 2) return 10;
return 15;
}
/**
* 英雄卡按 rarity 分配抽取权重(几何递减,高等级越稀有)
* 梯度:lv1=40, lv2=25, lv3=15, lv4=8, lv5=3
*/
const HERO_WEIGHT_BY_LV: Record<number, number> = {
1: 40, 2: 25, 3: 15, 4: 8, 5: 3,
};
function getHeroWeight(rarity: number): number {
return HERO_WEIGHT_BY_LV[rarity] ?? HERO_WEIGHT_BY_LV[1];
}
// 动态生成英雄卡池:所有英雄统一生成 lv1 卡牌
HeroList.forEach(uuid => {
const hero = HeroInfo[uuid];
if (!hero) return;
HeroCardPoolList.push({
uuid: hero.uuid,
cost: getHeroCost(hero.rarity ?? 1),
weight: getHeroWeight(hero.rarity ?? 1),
rarity: hero.rarity ?? 1,
});
});
// ==================== 英雄强度评分公式 ====================
/** 英雄强度公式调参权重(可在编辑器或运行时热调)
* 说明:
* - 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/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_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;
}
/**
* 解析普攻技能在目标英雄等级下的有效 overrides。
* 取 lv_entries 中 ≤hero_lv 的最大档,与基础 overrides 浅合并(档位字段优先)。
* Why: 普攻技能与触发技能对齐"英雄等级驱动成长"语义,且下游读取 skills[uuid].overrides 无需感知分档。
*/
export function resolveSkillOverrides(skill: HSkillInfo, hero_lv: number): SkillOverrides | undefined {
if (!skill.lv_entries || skill.lv_entries.length === 0) return skill.overrides;
let pick: LvSkillEntry | undefined;
for (const e of skill.lv_entries) {
if (e.lv <= hero_lv && (!pick || e.lv > pick.lv)) pick = e;
}
if (!pick) return skill.overrides;
return { ...skill.overrides, ...pick.overrides };
}
/** 解析驻场光环在目标等级下的有效词条列表(取 ≤lv 的最大档) */
export function resolveFieldByLv(field: LvFieldEntry[] | undefined, lv: number): FieldEntry[] {
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 : [];
}
/** 计算目标等级下额外属性加成(成长类型每级递增 + bonus 档位累加;bonus 中 hp/ap/def 为百分比,基数取"基础+成长"快照,多档加法叠加) */
function getEvolveBonuses(hero: heroInfo, targetLv: number): { hp: number, ap: number, def: number } {
const lv = Math.max(1, targetLv);
// 成长类型线性增量(仅英雄生效,怪物无 grow_type 时走 Warrior 基准但不影响平衡,因怪物通常不填)
const grow = hero.fac === FacSet.HERO ? calcGrowBonus(hero, lv) : { hp: 0, ap: 0, def: 0 };
let hp = grow.hp;
let ap = grow.ap;
let def = grow.def;
if (hero.bonus) {
// 百分比基数:基础值 + 成长快照(不含 bonus 自身,避免滚雪球)
const snapHp = hero.hp + grow.hp;
const snapAp = hero.ap + grow.ap;
const snapDef = hero.def + grow.def;
let hpP = 0, apP = 0, defP = 0;
for (const e of hero.bonus) {
if (e.lv > lv) continue;
hpP += e.attrs.hp ?? 0;
apP += e.attrs.ap ?? 0;
defP += e.attrs.def ?? 0;
// crt/frz/stun/para 为固定百分点,由运行时直接累加到概率属性,此处不结算
}
hp += Math.round(snapHp * hpP / 100);
ap += Math.round(snapAp * apP / 100);
def += Math.round(snapDef * defP / 100);
}
return { hp, ap, def };
}
/** 计算目标等级下的有效 HP/AP/DEF(固定基础值 + 成长递增与一次性加成) */
export function getEffectiveStats(hero: heroInfo, targetLv: number): { hp: number, ap: number, def: number } {
const bonuses = getEvolveBonuses(hero, targetLv);
return {
hp: hero.hp + bonuses.hp,
ap: hero.ap + bonuses.ap,
def: hero.def + bonuses.def,
};
}
/**
* 计算英雄展示用最终属性(含品质系数),供 UI 面板与运行时对齐口径。
* 公式:基础值 × 品质系数 + 成长 + bonus(lv12 专项已移除,由 bonus 配置接管)。
* @param hero 英雄配置
* @param targetLv 目标等级(≥1)
* @returns 含品质的最终 hp/ap/def(已取整)
*/
export function getHeroDisplayStats(hero: heroInfo, targetLv: number): { hp: number, ap: number, def: number } {
const lv = Math.max(1, Math.floor(targetLv));
const coef = getHeroQualityCoef(hero.rarity ?? 1);
const eff = getEffectiveStats(hero, lv);
return {
hp: Math.round(hero.hp * coef) + (eff.hp - hero.hp),
ap: Math.round(hero.ap * coef) + (eff.ap - hero.ap),
def: Math.round(hero.def * coef) + (eff.def - hero.def),
};
}
/** 获取英雄普通攻击间隔(取 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_FIELD_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;
}
/**
* 从 dead 触发配置中解析最大复活次数(revive_count)。
* 遍历所有 dead 技能的 overrides,取 revive_count 最大值。
* @param dead 死亡触发配置
* @param lv 英雄等级
* @returns 最大复活次数,无复活配置时返回 0
*/
export function resolveMaxReviveCount(dead: TriggerGrouped | undefined, lv: number): number {
const triggers = resolveTriggerByLv(dead, lv);
let maxRevive = 0;
for (const t of triggers) {
const count = t.overrides?.revive_count ?? 0;
if (count > maxRevive) maxRevive = count;
}
return maxRevive;
}
/** 计算触发技在目标时间窗内的触发次数 */
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:
return getWaveCount(seconds);
case SkillTriggerType.Dead:
// 死亡触发次数 = 回合数 × (1 + 最大复活次数),复活从 dead 配置中提取
const maxRevive = resolveMaxReviveCount(hero.dead, FightSet.HERO_MAX_LV);
return getWaveCount(seconds) * (1 + maxRevive);
}
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;
case Attrs.dodge:
case Attrs.accuracy:
value += modValue * weights.W_control;
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, hpEff: number, 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:
// 永久 buff 已改为百分比口径:value 是百分比,需先换算为基础 ap 的绝对增量
return ((value / 100) * apEff / cd) * weights.W_DPS_PER_SEC * seconds;
case Attrs.hp_max:
case Attrs.hp:
// 永久 buff 已改为百分比口径:value 是百分比,需先换算为基础 hp 的绝对增量
return (value / 100) * hpEff * 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.dodge:
case Attrs.accuracy:
return value * weights.W_control;
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 { hp: hpEff, 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:
// 护盾为数值减免型:1 点护盾 ≈ 1 点预期伤害减免
return (config.ap || 0) * weights.W_shield;
case SkillKind.Support:
return calcSupportEffectValue(config, hpEff, 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;
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/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.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 };
}
/** 计算驻场光环技能在时间窗内的总价值(value 由词条携带,fs 提供类型元数据) */
function calcFieldSkillValue(fs: FieldSkillConfig, value: number, hpEff: number, apEff: number, cd: number, scopeMul: number, seconds: number): number {
const weights = HERO_POWER_WEIGHTS;
const dps = apEff / cd;
switch (fs.type) {
case FieldSkillType.HeroAtk:
return value * dps * scopeMul * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroHp:
return value * hpEff * scopeMul * weights.W_HP;
case FieldSkillType.HeroSpeed:
return value * dps * scopeMul * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroCrit:
return value * dps * scopeMul * 0.5 * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroCritDamage:
return value * dps * scopeMul * 0.05 * weights.W_DPS_PER_SEC * seconds;
case FieldSkillType.HeroStun:
// 风怒机制已停用: 强度评估不再计算风怒光环
// case FieldSkillType.HeroWindFury:
case FieldSkillType.HeroPuncture:
case FieldSkillType.HeroPunctureDmg:
return value * scopeMul * weights.W_control * 100;
default:
return value * scopeMul * weights.W_control * 10;
}
}
/** 计算驻场光环的详细价值 */
function calcFieldPowerDetailed(entries: FieldEntry[] | undefined, hero: heroInfo, targetLv: number, seconds: number): { total: number, items: FieldSkillEval[] } {
if (!entries || entries.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_FIELD_NUM;
let total = 0;
const items: FieldSkillEval[] = [];
for (const entry of entries) {
const fs = FieldSkillSet[entry.uuid];
if (!fs) continue;
const value = calcFieldSkillValue(fs, entry.value, hpEff, apEff, cd, scopeMul, seconds) * weights.W_field_alive;
total += value;
items.push({ uuid: entry.uuid, name: fs.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 dead = hero.dead ? calcTriggerPowerDetailed(resolveTriggerByLv(hero.dead, targetLv), hero, targetLv, SkillTriggerType.Dead, seconds) : { total: 0, items: [] as TriggerSkillEval[] };
const fieldEntries = resolveFieldByLv(hero.field, targetLv);
const field = fieldEntries.length > 0 ? calcFieldPowerDetailed(fieldEntries, hero, targetLv, seconds) : { total: 0, items: [] as FieldSkillEval[] };
let reviveValue = 0;
// 复活价值从 dead 触发配置中提取(revive_hp / revive_count)
const deadTriggers = resolveTriggerByLv(hero.dead, targetLv);
for (const t of deadTriggers) {
const reviveHp = t.overrides?.revive_hp;
const reviveCount = t.overrides?.revive_count ?? 0;
if (reviveHp !== undefined && reviveCount > 0) {
reviveValue = hpEff * (reviveHp / 100) * reviveCount * weights.W_revive * getWaveCount(seconds);
}
}
const total = hpValue + dpsValue + atking.total + atked.total + fstart.total + dead.total + field.total + reviveValue;
return {
total,
breakdown: {
hp: hpValue,
dps: dpsValue,
atking: atking.total,
atked: atked.total,
fstart: fstart.total,
dead: dead.total,
field: field.total,
revive: reviveValue,
},
triggerSkills: [...atking.items, ...atked.items, ...fstart.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 = 5001, 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;
}