Files
pixelheros/assets/script/game/common/config/heroSet.ts
panFD 8ce83dc5e2 chore: 停用风怒机制并移除相关所有代码
全面移除游戏中风怒相关的所有内容,包括属性、技能、天赋、成就、UI展示、配置数据和结算逻辑,清理所有残留的风怒机制代码和配置项。
2026-08-24 23:48:40 +08:00

1490 lines
66 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,越小越快)
* 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 }> = {
[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 },
[HGrowType.Archer]: { hp: 0.8, ap: 1.3 },
};
/**
* 英雄位置类型(职业定位)。
* 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]: "辅助",
};
/**
* 职业基础属性模板(仅英雄使用,怪物无 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 基础值与 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", // 战斗开始 先手
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,
}
/**
* 触发技能标准命名表(按触发方式 → 技能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 风怒光环名称已移除
// 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)
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: 触发所需的受击次数
[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[];
}
/**
* 英雄卡配置(CHeroComp 专用,从 CardConfig 精简)
* 仅保留英雄卡渲染和交互必需的字段
*/
export interface HeroCardConfig {
uuid: number;
name?: string;
info?: string;
cost: number;
card_lv: number;
base_card_lv?: number;
}
/**
* 英雄卡池条目(含费用和权重,用于 MissionCardComp 抽卡)
*/
export interface HeroCardPoolEntry {
uuid: number;
cost: number;
weight: number;
card_lv: number;
}
/** 英雄卡池:由 HeroList 动态生成(见文件末尾初始化代码) */
export const HeroCardPoolList: HeroCardPoolEntry[] = [];
/**
* 技能基础信息接口
*/
export interface HSkillInfo {
uuid: number; // 唯一标识(技能6000段等)
lv: number; // 技能等级
cd: number; // 技能cd
ccd: number; // 占位当前cd,用于cd计时
overrides?: SkillOverrides; // 角色专属参数覆盖(全等级生效,作为底)
lv_entries?: LvSkillEntry[]; // 按英雄等级分档(按 lv 升序,运行时取 ≤英雄等级 的最大档)
}
/**
* 普攻技能分档配置:达到 lv 级英雄时此档 overrides 生效(与基础 overrides 浅合并,档位优先)。
* s_lv 标注此档对应的技能等级(SkillLv 枚举),便于面板显示"技能Lv.x"。
*/
export interface LvSkillEntry {
lv: number; // 达到该英雄等级时此档生效
s_lv?: SkillLv; // 此档对应的技能等级(标注用)
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;
}
/*
*=============英雄配置列表================
* 几何王国复刻版 — 依据 英雄设计指引.md(A/B 级复刻英雄)配置
*
* 规则:lv2 解锁触发技能(atking/atked/fstart),lv3/5/7 大招走 lv_entries 分档成长,
* lv9 card_lv 4/5 配 field 光环,card_lv 3 配 ap_bonus/hp_bonus 基础属性+50%
* 编号:本批复刻英雄集中于 5001~5009,card_lv 按配置(不遵循段位规则)
*/
// @hero-setup:region-begin
export const HeroInfo: Record<number, heroInfo> = {
// ========== 几何王国复刻英雄(5001~5009,依据 英雄设计指引.md) ==========
// 5001 紫电魔女 — atking 麻痹 + 大招 6203 大能量波(击退/麻痹)+ 攻击光环(深渊女王复刻)
5001: {
uuid: 5001, name: "紫电魔女", path: "hm1", fac: FacSet.HERO, card_lv: 4, 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: {
// 普攻:紫魔球底座 + overrides 注入麻痹
6010: { uuid: 6010, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, para: 30 } },
// 大招:大能量波,独立 cd,按英雄等级分档成长
6203: {
uuid: 6203, lv: 1, cd: 8, ccd: 0,
overrides: { ap: 250, bck: 30, para: 40, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 250, bck: 60, para: 40, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 300, bck: 90, timed_buff_id: 7005, para: 50, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 400, timed_buff_id: 7025, para: 70, summon_count: 3 } },
],
},
},
atking: {
6010: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 3, overrides: { para: 100 } },
],
},
field: [
{ lv: 9, uuids: [{ uuid: 7002, value: 0.15 }] },
],
infos: [
"解锁紫魔球:造成攻击力100%的伤害,30%概率麻痹",
"解锁能量波:对敌人造成攻击力250%的伤害并击退30,40%概率麻痹",
"电击精通:普攻每3次必定麻痹目标",
"能量波强化:击退提升至60",
"雷暴领域:能量波附带中毒,伤害300%且击退90,50%概率麻痹",
"—",
"雷霆万钧:能量波伤害400%,命中附加麻痹(70%概率)",
"—",
"魔女威压:全队攻击光环+15%",
],
info: "",
},
// 5002 刀刀暴击 — atking 暴击 + 大招 6100 光闪(出血/多段)+ 暴击/暴伤双光环(剑圣复刻)
5002: {
uuid: 5002, name: "刀刀暴击", path: "hk2", fac: FacSet.HERO, card_lv: 5, 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 + 15, def: HERO_ROLE_BASE[HRole.Warrior].def,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
// 大招:光闪,独立 cd,按英雄等级分档成长
6100: {
uuid: 6100, lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7007 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, hit_count: 8, num: 1 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 360, bck: 50 } },
],
},
},
atking: {
6004: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 3, overrides: { crt: 30 } },
],
},
field: [
{ lv: 9, uuids: [{ uuid: 7004, value: 0.12 }, { uuid: 7005, value: 0.2 }] },
],
infos: [
"解锁攻击:造成攻击力100%的伤害",
"解锁光闪:对周围敌人造成攻击力150%的伤害",
"致命节奏:普攻每3次暴击强化(暴击+30)",
"刃之血:光闪附加出血",
"分身斩:光闪伤害180%,8命中并双发",
"—",
"剑刃风暴:光闪伤害360%并击退全体敌人50",
"—",
"剑圣之意:全队暴击光环+12%、暴伤光环+20%",
],
info: "",
},
// 5003 格挡反杀 — fstart 剑气 + atked 护盾 + 大招 6103 闪电斩(减攻)(剑豪复刻)
5003: {
uuid: 5003, name: "格挡反杀", path: "hk4", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, grow_type: HGrowType.Warrior, role: HRole.Warrior, hp: HERO_ROLE_BASE[HRole.Warrior].hp + 10, ap: HERO_ROLE_BASE[HRole.Warrior].ap + 5, def: HERO_ROLE_BASE[HRole.Warrior].def + 5,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
// 大招:闪电斩,独立 cd,按英雄等级分档成长
6103: {
uuid: 6103, lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, para: 40, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7006, para: 40, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, timed_buff_id: 7006, buff_value: -15, para: 50, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 200, hit_count: 6, bck: 40, para: 60, summon_count: 3 } },
],
},
},
atked: {
6301: [
{ lv: 5, s_lv: SkillLv.Lv1, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 2 } },
],
},
fstart: {
6200: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 1, overrides: { ap: 500 } },
],
},
field: [
{ lv: 9, uuids: [{ uuid: 7018, value: 1 }] },
],
infos: [
"解锁攻击:造成攻击力100%的伤害",
"解锁闪电斩:对周围敌人造成攻击力150%的伤害,40%概率麻痹",
"三十六烦恼凤:入场释放高伤剑气(攻击力500%)",
"闪电斩强化:命中降低敌方攻击",
"罗生门:受击每4次获得2层护盾,闪电斩伤害180%且减攻强化(50%概率麻痹)",
"—",
"炼狱鬼斩:闪电斩伤害200%,6命中并击退40(60%概率麻痹)",
"—",
"攻击强化:攻击触发技能次数+1",
],
info: "",
},
// 5004 冻住不谢 — atking 冰冻 + 大招 6203 大能量波(冰冻链)+ 击晕光环(巫妖王复刻)
5004: {
uuid: 5004, name: "冻住不谢", path: "hm2", fac: FacSet.HERO, card_lv: 4, 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 + 5, def: HERO_ROLE_BASE[HRole.Mage].def + 5,
skills: {
6009: { uuid: 6009, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
// 大招:大能量波,独立 cd,按英雄等级分档成长
6203: {
uuid: 6203, lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, frz: 15, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, frz: 30, hit_count: 8, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 200, timed_buff_id: 7003, summon_count: 3 } },
],
},
},
atking: {
6009: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 3, overrides: { timed_buff_id: 7003 } },
],
},
field: [
{ lv: 9, uuids: [{ uuid: 7003, value: 0.1 }] },
],
infos: [
"解锁蓝魔球:造成攻击力100%的伤害",
"解锁能量波:直线能量伤害150%",
"霜寒之触:普攻每3次附加冰冻(≈33%概率)",
"霜冻连锁:能量波15%概率冰冻",
"连环霜冻:能量波冰冻30%,8命中且伤害180%",
"—",
"绝对零度:能量波伤害200%且命中必冰冻",
"—",
"冰霜领域:全队击晕光环+10%",
],
info: "",
},
// 5005 叠甲骑士 — 护盾大招 + fstart 防御 + dead 治疗 + revive 回光返照(黑暗骑士复刻)
5005: {
uuid: 5005, name: "叠甲骑士", path: "hk1", fac: FacSet.HERO, card_lv: 5, 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, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
// 大招位辅助技能:护盾,按英雄等级分档成长(护盾层数)
6301: {
uuid: 6301, lv: 1, cd: 8, ccd: 0,
overrides: { TGroup: TGroup.Self, ap: 3, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Self, ap: 5, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Self, ap: 6, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { TGroup: TGroup.Self, ap: 8, summon_count: 3 } },
],
},
},
atked: {
6004: [
{ lv: 5, s_lv: SkillLv.Lv1, t_num: 4, overrides: { timed_buff_id: 7006 } },
],
},
fstart: {
6412: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 50 } },
],
},
dead: {
6302: [
{ lv: 7, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Ally, ap: 200 } },
],
},
field: [
{ lv: 9, uuids: [{ uuid: 7007, value: 0.15 }, { uuid: 7019, value: 1 }] },
],
// 回光返照:濒死回血(6501.ap=50 即恢复50%生命,upr 为每级追加次数,非血量百分比)
revive: [
{ lv: 7, s_uuid: 6501, r_num: 1, upr: 0 },
],
infos: [
"解锁攻击与护盾:自身获得3层抵挡护盾",
"铁壁壁垒:入场全队防御+50",
"护盾强化:护盾层数提升至5",
"—",
"反击减攻:受击每4次附加减攻,护盾层数6",
"—",
"死亡缠绕+回光返照:死亡治疗最低血友军,濒死回血续命;护盾层数8",
"—",
"不朽甲胄:全队生命光环+15%、受击触发次数+1",
],
info: "",
},
// 5006 光明奶爸 — 治疗大招 + atking 自疗 + fstart 防御 + 生命光环(光明骑士复刻)
5006: {
uuid: 5006, name: "光明奶爸", path: "hh1", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Long, grow_type: HGrowType.Support, role: HRole.Support, hp: HERO_ROLE_BASE[HRole.Support].hp + 15, ap: HERO_ROLE_BASE[HRole.Support].ap, def: HERO_ROLE_BASE[HRole.Support].def + 10,
skills: {
6012: { uuid: 6012, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Normal].cd, ccd: 0 },
// 大招:治疗,独立 cd,按英雄等级分档成长
6302: {
uuid: 6302, lv: 1, cd: 8, ccd: 0,
overrides: { TGroup: TGroup.Team, ap: 300, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Team, ap: 400, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Team, ap: 450, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { TGroup: TGroup.Team, ap: 450, timed_buff_id: 7010, summon_count: 3 } },
],
},
},
atking: {
6302: [
{ lv: 5, s_lv: SkillLv.Lv1, t_num: 3, overrides: { TGroup: TGroup.Self, ap: 100 } },
],
},
fstart: {
6412: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 1, overrides: { TGroup: TGroup.Team, ap: 30 } },
],
},
field: [
{ lv: 9, uuids: [{ uuid: 7007, value: 0.15 }] },
],
infos: [
"解锁红药瓶:造成攻击力100%的伤害",
"解锁治疗:恢复全队生命(攻击力300%)",
"圣光庇佑:入场全队防御+30",
"治疗强化:治疗量提升至400%",
"圣洁之锤:攻击每3次自疗(攻击力100%),治疗量450%",
"—",
"生命灌注:治疗附带再生(持续回血)",
"—",
"光明领域:全队生命光环+15%",
],
info: "",
},
// 5007 微醺战神 — atking 击退 + 大招 6101 气斩(易伤),lv9 属性补偿(酒仙复刻)
5007: {
uuid: 5007, name: "微醺战神", path: "hk3", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp + 15, ap: HERO_ROLE_BASE[HRole.Tank].ap + 5, def: HERO_ROLE_BASE[HRole.Tank].def + 10,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
// 大招:气斩,独立 cd,按英雄等级分档成长
6101: {
uuid: 6101, lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7002, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 180, bck: 60, timed_buff_id: 7002, buff_value: 20, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 220, bck: 80, summon_count: 3 } },
],
},
},
atking: {
6004: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 3, overrides: { bck: 40 } },
],
},
// card_lv 3:lv9 无光环,改为基础属性+50%
ap_bonus: [{ lv: 9, value: 0.5 }],
hp_bonus: [{ lv: 9, value: 0.5 }],
infos: [
"解锁攻击:造成攻击力100%的伤害",
"解锁气斩:对周围敌人造成攻击力150%的伤害",
"雷霆一击:普攻每3次附加击退40",
"醉拳浸染:气斩附加易伤",
"酒劲上头:气斩伤害180%,击退60且易伤强化",
"—",
"醉里乾坤:气斩伤害220%,击退80",
"—",
"千杯不醉:基础攻击与生命+50%",
],
info: "",
},
// 5008 眩晕暴击哥 — atking 暴击 + 大招 6104 开山斧(击晕)+ 暴伤光环(齐天大圣复刻)
5008: {
uuid: 5008, name: "眩晕暴击哥", path: "hk5", fac: FacSet.HERO, card_lv: 5, 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,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
// 大招:开山斧,独立 cd,按英雄等级分档成长
6104: {
uuid: 6104, lv: 1, cd: 8, ccd: 0,
overrides: { ap: 300, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 300, stun: 20, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 350, stun: 35, hit_count: 8, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 400, timed_buff_id: 7004, summon_count: 3 } },
],
},
},
atking: {
6004: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 3, overrides: { crt: 25 } },
],
},
field: [
{ lv: 9, uuids: [{ uuid: 7005, value: 0.25 }] },
],
infos: [
"解锁攻击:造成攻击力100%的伤害",
"解锁开山斧:劈向前方敌人造成攻击力300%的伤害",
"火眼金睛:普攻每3次暴击强化(暴击+25)",
"金箍棒影:开山斧20%概率击晕",
"大圣之怒:开山斧击晕35%,8命中且伤害350%",
"—",
"定海神针:开山斧伤害400%且命中必击晕",
"—",
"斗战胜意:全队暴伤光环+25%",
],
info: "",
},
// 5009 铁壳斧弟 — atked 叠防 + atking 自疗 + 大招 6101 气斩,lv9 属性补偿(斧小王复刻)
5009: {
uuid: 5009, name: "铁壳斧弟", path: "hc1", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.Tank, hp: HERO_ROLE_BASE[HRole.Tank].hp + 10, ap: HERO_ROLE_BASE[HRole.Tank].ap + 5, def: HERO_ROLE_BASE[HRole.Tank].def + 15,
skills: {
6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 },
// 大招:气斩,独立 cd,按英雄等级分档成长
6101: {
uuid: 6101, lv: 1, cd: 8, ccd: 0,
overrides: { ap: 150, summon_count: 1 },
lv_entries: [
{ lv: 3, s_lv: SkillLv.Lv2, overrides: { ap: 180, summon_count: 1 } },
{ lv: 5, s_lv: SkillLv.Lv3, overrides: { ap: 200, summon_count: 2 } },
{ lv: 7, s_lv: SkillLv.Lv4, overrides: { ap: 220, bck: 40, summon_count: 3 } },
],
},
},
atking: {
6302: [
{ lv: 5, s_lv: SkillLv.Lv1, t_num: 4, overrides: { TGroup: TGroup.Self, ap: 120 } },
],
},
atked: {
// 坚硬皮肤:借 6513 防御爆发底座注入 7023 防御强化(+50%,可无限叠层)
6513: [
{ lv: 2, s_lv: SkillLv.Lv1, t_num: 2, overrides: { TGroup: TGroup.Self, timed_buff_id: 7023, buff_duration: 10 } },
],
},
// card_lv 3:lv9 无光环,改为基础属性+50%
ap_bonus: [{ lv: 9, value: 0.5 }],
hp_bonus: [{ lv: 9, value: 0.5 }],
infos: [
"解锁攻击:造成攻击力100%的伤害",
"解锁气斩:对周围敌人造成攻击力150%的伤害",
"坚硬皮肤:受击每2次叠加防御强化(持续10秒,可叠层)",
"气斩强化:伤害180%",
"嗜血战斧:攻击每4次自疗(攻击力120%),气斩伤害200%",
"—",
"奋力一掷:气斩伤害220%并击退40",
"—",
"铁壳觉醒:基础攻击与生命+50%",
],
info: "",
},
/*
*=============怪物配置列表================
* 性能基准:1 级怪物与 1 级英雄单体性能持平 ——
* 近战怪基准 hp300/ap22/cd1.20,远程怪基准 hp160/ap28/cd1.20,
* 重型/Boss 以更高 hp 换取更低 DPS,承担"墙"与"压场"定位。
* 怪物普攻统一使用 SkillSet 基础单体攻击(6001~6012 段),
* 并通过 overrides.ap=100 显式声明伤害为攻击力的 100%。
* 运行时最终属性 = 本表基础值 × RogueConfig.MON_HP_MUL / MON_AP_MUL
* (Boss 额外 × BOSS_HP_BONUS_MUL),校准目标:整场战斗双方对砍 ≈ 30s。
*/
// 基础怪物 (全部固定点位站桩攻击,HType仅决定是前排还是后排)
// 前排怪物 — 近战镜像 1 级英雄基准(hp300/ap22/cd1.20),变体微分定位
6001: {
uuid: 6001, name: "兽人战士", path: "m1", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 300, ap: 22, def: 20, speed: 70,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "基础前排怪, 与1级近战英雄持平"
},
6002: {
uuid: 6002, name: "兽人精锐战士", path: "m2", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Melee, hp: 340, ap: 26, def: 25, speed: 110,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0 } }, info: "进阶前排怪, 更快更痛"
},
6003: {
uuid: 6003, name: "兽人重装兵", path: "m3", fac: FacSet.MON, lv: 1, type: HType.Melee, monType: MonType.Heavy, hp: 800, ap: 14, def: 60, speed: 50,
skills: { 6004: { uuid: 6004, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.VerySlow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "重型坦克怪, 高HP低攻承伤位"
},
// 后排怪物 — 远程镜像 1 级法师基准(hp160/ap28/cd1.20),变体微分定位
6004: {
uuid: 6004, name: "兽人射手", path: "m4", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Long, hp: 160, ap: 28, def: 8, speed: 70,
skills: { 6006: { uuid: 6006, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100 } } }, info: "后排输出怪, 与1级远程英雄持平"
},
6005: {
uuid: 6005, name: "兽人刺客", path: "m5", fac: FacSet.MON, lv: 1, type: HType.Long, monType: MonType.Assassin, hp: 130, ap: 26, def: 5, 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, type: HType.Melee, monType: MonType.MeleeBoss, hp: 900, ap: 20, def: 40, 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, type: HType.Long, monType: MonType.Support, hp: 240, ap: 18, def: 10, 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, type: HType.Long, monType: MonType.Summoner, hp: 220, ap: 24, def: 10, speed: 70,
skills: { 6010: { uuid: 6010, lv: 1, cd: AtkSpeedSet[AtkSpeedLv.Slow].cd, ccd: 0, overrides: { ap: 100, hit_count: 2 } } }, info: "后排召唤系法师怪"
},
// BOSS怪物 — 本表 hp/ap 仅作外观/技能档位参考,运行时面板由 RogueConfig 的
// BOSS_BASE_HP / BOSS_BASE_AP(初始英雄 2 倍强度)统一决定,不读取本表数值
6101: {
uuid: 6101, name: "兽人首领-双刀战士", path: "mb1", fac: FacSet.MON, lv: 6, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1200, ap: 24, def: 45, 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, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1500, ap: 18, def: 55, 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, type: HType.Long, monType: MonType.LongBoss, hp: 1000, ap: 28, def: 25, 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, type: HType.Long, monType: MonType.LongBoss, hp: 1100, ap: 24, def: 25, 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, type: HType.Long, monType: MonType.LongBoss, hp: 1000, ap: 30, def: 20, 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, type: HType.Melee, monType: MonType.MeleeBoss, hp: 1800, ap: 20, def: 60, 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[] = [
// 几何王国复刻英雄(5001~5009)
5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008, 5009,
];
// @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[]; // 低配替代阵容(card_lv 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(cardLv: number): number {
if (cardLv === 1) return 5;
if (cardLv === 2) return 10;
return 15;
}
/**
* 英雄卡按 card_lv 分配抽取权重(几何递减,高等级越稀有)
* 梯度: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(cardLv: number): number {
return HERO_WEIGHT_BY_LV[cardLv] ?? HERO_WEIGHT_BY_LV[1];
}
// 动态生成英雄卡池:所有英雄统一生成 lv1 卡牌
HeroList.forEach(uuid => {
const hero = HeroInfo[uuid];
if (!hero) return;
HeroCardPoolList.push({
uuid: hero.uuid,
cost: getHeroCost(hero.card_lv ?? 1),
weight: getHeroWeight(hero.card_lv ?? 1),
card_lv: hero.card_lv ?? 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 : [];
}
/** 解析复活技能在目标等级下的有效配置(取 ≤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_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;
}
/** 计算触发技在目标时间窗内的触发次数 */
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:
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, 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:
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;
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 + 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;
}