Files
pixelheros/assets/script/game/common/config/heroSet.ts
panFD 450a8b81e5 refactor(field): 重构驻场光环数据结构,分离元数据与数值
1.  新增FieldEntry类型,将驻场词条的uuid与生效数值分离
2.  重构FieldSkillSet,移除各档位重复配置,仅保留基础元数据
3.  更新所有使用驻场词条的业务代码,适配新的数据结构
4.  修复数值渲染逻辑,使用词条携带的实际数值而非配置固化值
2026-08-11 22:36:28 +08:00

1341 lines
60 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轴间隔
}
/**
* 英雄成长类型(决定每级 hp/ap 标准增量系数)。
* Why: 不同定位英雄的成长曲线差异化,避免"一刀切"导致坦克/刺客同强度。
*/
export enum HGrowType {
Tank = 0, // 坦克:高 hp 低 ap
Warrior = 1, // 战士:均衡
Assassin = 2, // 刺客:低 hp 高 ap
Mage = 3, // 法师:中 hp 高 ap
Support = 4, // 辅助:中 hp 低 ap
}
/** 成长类型系数表(每级增量 = 英雄基础属性 × 对应系数) */
export const HERO_GROW_COEF: Record<HGrowType, { hp: number; ap: number }> = {
[HGrowType.Tank]: { hp: 1.5, ap: 0.6 },
[HGrowType.Warrior]: { hp: 1.0, ap: 1.0 },
[HGrowType.Assassin]: { hp: 0.7, ap: 1.4 },
[HGrowType.Mage]: { hp: 0.9, ap: 1.3 },
[HGrowType.Support]: { hp: 1.1, ap: 0.7 },
};
/**
* 计算英雄在目标等级下的累计属性成长增量(线性:每级加一份"基础属性×系数")。
* 公式:累计 = 基础属性 × 类型系数 × (lv - 1)。
* Why: 以英雄自身基础值为基数,自动适配低/高费卡的成长占比,避免全局固定值失衡;
* 线性曲线在无限升级下不会指数爆炸,强度平滑可控。
* @param hero 英雄配置(取 hp/ap 基础值与 grow_type
* @param targetLv 目标等级≥1
* @returns 累计 hp/ap 增量(已取整)
*/
export function calcGrowBonus(hero: Pick<heroInfo, "hp" | "ap" | "grow_type">, targetLv: number): { hp: number; ap: 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),
};
}
/**
* 特殊触发技能类型
*/
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: "凤凰涅槃", // 死亡后原地复活
},
// 驻场光环field英雄语境专属命名名字直接带"光环"便于玩家理解
[SkillTriggerType.Field]: {
7002: "攻击光环", // 英雄攻击力提升
7003: "击晕光环", // 英雄击晕概率提升
7004: "暴击光环", // 英雄暴击率提升
7005: "暴伤光环", // 英雄暴击伤害提升
7006: "攻速光环", // 英雄攻击速度提升
7007: "生命光环", // 英雄最大生命提升
7008: "风怒光环", // 英雄风怒概率提升
7009: "穿刺光环", // 英雄穿刺概率提升
},
}
/**
* 查询触发技能在指定触发语境下的标准名称。
* @param type 触发类型SkillTriggerType
* @param s_uuid 技能ID
* @returns 语境专属名称;未配置时回退 SkillSet 通用名称
*/
export function getTriggerSkillName(type: SkillTriggerType, s_uuid: number): string {
const group = TriggerSkillNameSet[type];
if (group) {
const direct = group[s_uuid];
if (direct) return direct;
}
// 驻场光环 uuid 存于 FieldSkillSet触发技能存于 SkillSet分别兜底
if (type === SkillTriggerType.Field) {
return FieldSkillSet[s_uuid]?.name ?? "";
}
return 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; // 攻击定位(近战/中程/远程)
grow_type?: HGrowType; // 成长类型(决定每级 hp/ap 标准增量,默认 Warrior
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[]>;
/**
* 驻场光环词条uuid 指向 FieldSkillSet 底座(类型/图标/名称元数据),
* value 为该词条实际生效数值(由配置处按档位指定,不再随 uuid 分档)。
*/
export interface FieldEntry {
uuid: number;
value: number;
}
/**
* 驻场光环按等级解锁:运行时取 ≤英雄等级 的最大 lv 档的词条列表。
*/
export interface LvFieldEntry {
lv: number;
uuids: FieldEntry[];
}
/**
* 复活技能按等级解锁:运行时取 ≤英雄等级 的最大 lv 档。
*/
export interface LvReviveEntry {
lv: number;
s_uuid: number;
r_num: number;
upr: number;
}
/**
* 额外属性加成按等级叠加:运行时累加所有 ≤英雄等级 的档位。
*/
export interface LvBonusEntry {
lv: number;
value: number;
}
/*
*=============英雄配置列表================
* v5 模板重塑版 — 按 HeroDesignSpec.md 规范统一配置
*
* 规则3档 lv1/3/5lv5 降 t_numatked/atking 5→4
* 品质card_lv = 1 + 能力加成(数值/范围/双技能)
* 编号5001-5099=card1, 5101-5199=card2, 5201-5299=card3, 5301-5399=card4, 5401-5499=card5
*/
export const HeroInfo: Record<number, heroInfo> = {
// ========== card_lv=15001-5005基础单体/默认范围 ==========
// 5001 铁壁战士 — atked 护盾标杆原5011
5001: {
uuid: 5001, name: "铁壁战士", path: "hk1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, hp: 300, ap: 28,
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
atked: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 3 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 4 } },
],
},
info: "",
},
// 5002 影袭刺客 — atking 自身攻击
5002: {
uuid: 5002, name: "影袭刺客", path: "hc1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, grow_type: HGrowType.Assassin, hp: 300, ap: 28,
skills: { 6003: { uuid: 6003, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
atking: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 1 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 3 } },
],
},
info: "",
},
// 5003 遗志将军 — dead 全队攻击
5003: {
uuid: 5003, name: "遗志将军", path: "hk2", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, hp: 300, ap: 28,
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: 3 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } },
],
},
info: "",
},
// 5004 破晓先知 — fstart 全队攻击
5004: {
uuid: 5004, name: "破晓先知", path: "hm1", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 143, ap: 40,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
fstart: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 3 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } },
],
},
info: "",
},
// 5005 战歌法师 — field 攻击光环
5005: {
uuid: 5005, name: "战歌法师", path: "hm2", fac: FacSet.HERO, card_lv: 1, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 143, ap: 40,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
field: [
{ lv: 1, uuids: [{ uuid: 7002, value: 0.1 }] },
{ lv: 3, uuids: [{ uuid: 7002, value: 0.2 }] },
{ lv: 5, uuids: [{ uuid: 7002, value: 0.3 }] },
],
info: "",
},
// ========== card_lv=25101-5105数值强化 ==========
// 5101 不死斗士 — atked 回血(更高数值)
5101: {
uuid: 5101, name: "不死斗士", path: "hk3", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, 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: 5, overrides: { TGroup: TGroup.Self, ap: 200 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 250 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 300 } },
],
},
info: "",
},
// 5102 致命杀手 — atking 暴击(更高数值)
5102: {
uuid: 5102, name: "致命杀手", path: "hc2", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, grow_type: HGrowType.Assassin, hp: 600, ap: 57,
skills: { 6003: { uuid: 6003, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Fast2].cd, ccd: 0 } },
atking: {
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: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Self, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
},
info: "",
},
// 5103 殉道勇士 — dead 全队护盾(更高数值)
5103: {
uuid: 5103, name: "殉道勇士", path: "hk4", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, hp: 600, ap: 57,
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: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
],
},
info: "",
},
// 5104 圣光祭司 — fstart 全队护盾(更高数值)
5104: {
uuid: 5104, name: "圣光祭司", path: "hm3", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 287, ap: 80,
skills: { 6013: { uuid: 6013, 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: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 4 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
],
},
info: "",
},
// 5105 风怒先知 — field 攻速光环
5105: {
uuid: 5105, name: "风怒先知", path: "hm1", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 287, ap: 80,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
field: [
{ lv: 1, uuids: [{ uuid: 7006, value: 0.1 }] },
{ lv: 3, uuids: [{ uuid: 7006, value: 0.2 }] },
{ lv: 5, uuids: [{ uuid: 7006, value: 0.3 }] },
],
info: "",
},
// 5106 破甲射手 — atking 自身穿透伤害计时buff增强
5106: {
uuid: 5106, name: "破甲射手", path: "ha1", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Long, grow_type: HGrowType.Assassin, hp: 287, ap: 80,
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
atking: {
6512: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7022, buff_value: 5, buff_duration: 5 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, timed_buff_id: 7022, buff_value: 7, buff_duration: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Self, timed_buff_id: 7022, buff_value: 10, buff_duration: 6 } },
],
},
info: "",
},
// ========== card_lv=35201-5205范围扩大 ==========
// 5201 怒血勇士 — atked 全队攻击(范围扩大)
5201: {
uuid: 5201, name: "怒血勇士", path: "hk5", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, hp: 900, ap: 85,
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
atked: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 1 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 2 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Team, ap: 3 } },
],
},
info: "",
},
// 5202 援护射手 — atking 队友攻击(范围扩大)
5202: {
uuid: 5202, name: "援护射手", path: "ha1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Assassin, hp: 430, ap: 120,
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } },
atking: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 1, ap: 1 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, ap: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 3, ap: 1 } },
],
},
info: "",
},
// 5203 传承卫士 — dead 全队生命(范围扩大)
5203: {
uuid: 5203, name: "传承卫士", path: "hk1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, hp: 900, ap: 85,
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow3].cd, ccd: 0 } },
dead: {
6402: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } },
],
},
info: "",
},
// 5204 晨光贤者 — fstart 全队暴击(范围扩大)
5204: {
uuid: 5204, name: "晨光贤者", path: "hm2", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 430, ap: 120,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid3].cd, ccd: 0 } },
fstart: {
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: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
},
info: "",
},
// 5205 精准术士 — field 暴击光环(范围扩大)
5205: {
uuid: 5205, name: "精准术士", path: "hm3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 430, ap: 120,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
field: [
{ lv: 1, uuids: [{ uuid: 7004, value: 0.1 }] },
{ lv: 3, uuids: [{ uuid: 7004, value: 0.2 }] },
{ lv: 5, uuids: [{ uuid: 7004, value: 0.3 }] },
],
info: "",
},
// ========== card_lv=45301-5305数值+范围 ==========
// 5301 复仇守护者 — atked 全队暴击(范围+数值)
5301: {
uuid: 5301, name: "复仇守护者", path: "hk2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, hp: 1200, ap: 113,
skills: { 6001: { uuid: 6001, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow1].cd, ccd: 0 } },
atked: {
6403: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 5, buff_duration: 5 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 10, buff_duration: 6 } },
],
},
info: "",
},
// 5302 破灭游侠 — atking 队友暴伤(范围+数值)
5302: {
uuid: 5302, name: "破灭游侠", path: "ha2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Assassin, hp: 573, ap: 160,
skills: { 6008: { uuid: 6008, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal1].cd, ccd: 0 } },
atking: {
6404: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 2, timed_buff_id: 7020, buff_value: 5, buff_duration: 5 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, hit_count: 3, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Team, hit_count: 4, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
],
},
info: "",
},
// 5303 亡语刺客 — dead 全队暴击+暴伤(双效果)
5303: {
uuid: 5303, name: "亡语刺客", path: "hc3", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, grow_type: HGrowType.Assassin, hp: 1200, ap: 113,
skills: { 6003: { uuid: 6003, 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: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7012, buff_value: 7, buff_duration: 5 } },
{ lv: 5, 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: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 7, buff_duration: 5 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, timed_buff_id: 7020, buff_value: 10, buff_duration: 6 } },
],
},
info: "",
},
// 5304 战吼术士 — fstart 全队攻击+生命(双效果)
5304: {
uuid: 5304, name: "战吼术士", path: "hm1", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 573, ap: 160,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid1].cd, ccd: 0 } },
fstart: {
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
],
6402: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 10 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 15 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 20 } },
],
},
info: "",
},
// 5305 领域贤者 — field 暴伤+攻速光环(双效果)
5305: {
uuid: 5305, name: "领域贤者", path: "hm2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 573, ap: 160,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Mid2].cd, ccd: 0 } },
field: [
{ lv: 1, uuids: [{ uuid: 7005, value: 0.2 }, { uuid: 7006, value: 0.1 }] },
{ lv: 3, uuids: [{ uuid: 7005, value: 0.4 }, { uuid: 7006, value: 0.2 }] },
{ lv: 5, uuids: [{ uuid: 7005, value: 0.6 }, { uuid: 7006, value: 0.3 }] },
],
info: "",
},
// ========== card_lv=55401-5405双技能+revive/field ==========
// 5401 不灭战魂 — atked 攻击 + revive双技能
5401: {
uuid: 5401, name: "不灭战魂", path: "hk3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, 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: 5, overrides: { TGroup: TGroup.Self, ap: 2 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 3 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 4 } },
],
},
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: "",
},
// 5402 战歌游侠 — atking 攻击 + field 攻速光环(双技能)
5402: {
uuid: 5402, name: "战歌游侠", path: "ha3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, grow_type: HGrowType.Assassin, 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.Self, ap: 2 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Self, ap: 3 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 4 } },
],
},
field: [
{ lv: 1, uuids: [{ uuid: 7006, value: 0.1 }] },
{ lv: 3, uuids: [{ uuid: 7006, value: 0.2 }] },
{ lv: 5, uuids: [{ uuid: 7006, value: 0.3 }] },
],
info: "",
},
// 5403 凤凰祭司 — dead 攻击+护盾 + revive双技能
5403: {
uuid: 5403, name: "凤凰祭司", path: "hk4", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, hp: 1500, ap: 142,
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 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
],
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } },
],
},
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: "",
},
// 5404 涅槃贤者 — fstart 护盾+攻击 + revive双技能
5404: {
uuid: 5404, name: "涅槃贤者", path: "hm3", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, grow_type: HGrowType.Mage, hp: 717, ap: 200,
skills: { 6013: { uuid: 6013, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal3].cd, ccd: 0 } },
fstart: {
6301: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 6 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 7 } },
],
6401: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 5 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 8 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 12 } },
],
},
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: "",
},
// 5405 圣言诗人 — atking 治疗 + field 生命光环(双技能)
5405: {
uuid: 5405, name: "圣言诗人", path: "hh1", fac: FacSet.HERO, card_lv: 5, lv: 1, type: HType.Long, grow_type: HGrowType.Support, hp: 717, ap: 200,
skills: { 6015: { uuid: 6015, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal2].cd, ccd: 0 } },
atking: {
6302: [
{ lv: 1, s_lv: SkillLv.Lv1, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 200 } },
{ lv: 3, s_lv: SkillLv.Lv2, t_num: 5, overrides: { TGroup: TGroup.Team, ap: 250 } },
{ lv: 5, s_lv: SkillLv.Lv3, t_num: 4, overrides: { TGroup: TGroup.Team, ap: 300 } },
],
},
field: [
{ lv: 1, uuids: [{ uuid: 7007, value: 0.1 }] },
{ lv: 3, uuids: [{ uuid: 7007, value: 0.2 }] },
{ lv: 5, uuids: [{ uuid: 7007, value: 0.3 }] },
],
info: "",
},
/*
*=============怪物配置列表================
* 基础近战型(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[] = [
// card_lv=1
5001, 5002, 5003, 5004, 5005,
// card_lv=2
5101, 5102, 5103, 5104, 5105, 5106,
// card_lv=3
5201, 5202, 5203, 5204, 5205,
// card_lv=4
5301, 5302, 5303, 5304, 5305,
// card_lv=5
5401, 5402, 5403, 5404, 5405,
];
// ==================== 英雄强度评分公式 ====================
/** 英雄强度公式调参权重(可在编辑器或运行时热调)
* 说明:
* - 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;
}
/** 解析驻场光环在目标等级下的有效词条列表(取 ≤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 : [];
}
/** 解析复活技能在目标等级下的有效配置(取 ≤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 一次性奖励 + 成长类型每级递增) */
function getEvolveBonuses(hero: heroInfo, targetLv: number): { hp: number, ap: number } {
const lv = Math.max(1, targetLv);
// 成长类型线性增量(仅英雄生效,怪物无 grow_type 时走 Warrior 基准但不影响平衡,因怪物通常不填)
const grow = hero.fac === FacSet.HERO ? calcGrowBonus(hero, lv) : { hp: 0, ap: 0 };
let hp = grow.hp;
let ap = grow.ap;
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);
return {
hp: hero.hp + bonuses.hp,
ap: hero.ap + bonuses.ap,
};
}
/** 获取英雄普通攻击间隔(取 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 };
}
/** 计算驻场光环技能在时间窗内的总价值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_MAX_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 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 fieldEntries = resolveFieldByLv(hero.field, targetLv);
const field = fieldEntries.length > 0 ? calcFieldPowerDetailed(fieldEntries, 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 = 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;
}