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 = { [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]: 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.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 }, }; /** * 英雄位置类型(职业定位)。 * 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.Tank]: "坦克", [HRole.Warrior]: "战士", [HRole.Assassin]: "刺客", [HRole.Archer]: "射手", [HRole.Mage]: "法师", [HRole.Support]: "辅助", }; /** * 计算英雄在目标等级下的累计属性成长增量(线性:每级加一份"基础属性×系数")。 * 公式:累计 = 基础属性 × 类型系数 × (lv - 1)。 * Why: 以英雄自身基础值为基数,自动适配低/高费卡的成长占比,避免全局固定值失衡; * 线性曲线在无限升级下不会指数爆炸,强度平滑可控。 * @param hero 英雄配置(取 hp/ap 基础值与 grow_type) * @param targetLv 目标等级(≥1) * @returns 累计 hp/ap 增量(已取整) */ export function calcGrowBonus(hero: Pick, 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> = { [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) role?: HRole; // 位置类型/职业定位(英雄专用,怪物用 monType 表达) 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; // 携带技能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; /** * 驻场光环词条: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/5,lv5 降 t_num(atked/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 = { // ========== card_lv=1(5001-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, role: HRole.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, role: HRole.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, role: HRole.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, role: HRole.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, role: HRole.Support, 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=2(5101-5105)数值强化 ========== // 5101 不死斗士 — atked 回血(更高数值) 5101: { uuid: 5101, name: "不死斗士", path: "hk3", fac: FacSet.HERO, card_lv: 2, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.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, role: HRole.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, role: HRole.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, role: HRole.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, role: HRole.Support, 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, role: HRole.Archer, 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=3(5201-5205)范围扩大 ========== // 5201 怒血勇士 — atked 全队攻击(范围扩大) 5201: { uuid: 5201, name: "怒血勇士", path: "hk5", fac: FacSet.HERO, card_lv: 3, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.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, role: HRole.Archer, 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, role: HRole.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, role: HRole.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, role: HRole.Support, 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=4(5301-5305)数值+范围 ========== // 5301 复仇守护者 — atked 全队暴击(范围+数值) 5301: { uuid: 5301, name: "复仇守护者", path: "hk2", fac: FacSet.HERO, card_lv: 4, lv: 1, type: HType.Melee, grow_type: HGrowType.Tank, role: HRole.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, role: HRole.Archer, 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, role: HRole.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, role: HRole.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, role: HRole.Support, 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=5(5401-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, role: HRole.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, role: HRole.Archer, 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, role: HRole.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, role: HRole.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, role: HRole.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, ]; // ==================== 英雄推荐阵容配置 ==================== /** * 推荐阵容条目。 * Why: 场上最多 3 个英雄(FightSet.HERO_MAX_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,供新手期引导) } /** * 推荐阵容表。 * 设计原则: * 1. 铁三角结构:1 前排(坦克/献祭)+ 1 增益(光环/先手)+ 1 主C * 2. 乘区分散:攻击/暴击/暴伤/攻速各占独立乘区,组合优先覆盖不同乘区避免稀释 * 3. 发动机冗余:献祭/反击流的发动机依赖前排挨打或死亡,revive 卡(5401/5403/5404)负责重复点火 */ export const HeroComboSet: Record = { // 8001 暴击爆发流 — 暴击率与暴伤双乘区互不稀释,成型最强 8001: { uuid: 8001, name: "暴击爆发流", heroes: [5301, 5302, 5402], desc: "复仇守护者挨打为全队提供暴击率,破灭游侠普攻为队友叠加暴伤,战歌游侠以极速普攻吃满暴击×暴伤双乘区完成收割。", }, // 8002 献祭复活流 — revive 让死亡发动机循环点火 8002: { uuid: 8002, name: "献祭复活流", heroes: [5403, 5303, 5102], desc: "凤凰祭司死亡为全队加攻击与护盾,复活后可再次献祭;亡语刺客死亡送出暴击+暴伤双增益,全部灌给主C致命杀手。", low_heroes: [5003, 5103, 5002], }, // 8003 铁桶反击流 — 挨打次数越多增益越多,最稳 8003: { uuid: 8003, name: "铁桶反击流", heroes: [5401, 5201, 5405], desc: "双前排持续挨打:怒血勇士为全队永久叠加攻击,不灭战魂自我强化并以复活兜底;圣言诗人治疗+生命光环保证前排挨得起。", }, // 8004 先手速攻流 — 开局 buff 窗口内快速收割,短回合最强 8004: { uuid: 8004, name: "先手速攻流", heroes: [5304, 5004, 5002], desc: "战吼术士与破晓先知双重开局战吼直接拉满全队攻击,影袭刺客凭最快攻速与自身攻击滚雪球在增益窗口内结束战斗。", low_heroes: [5004, 5005, 5002], }, // 8005 双光环平A流 — 攻击×攻速光环乘算,低配易成型 8005: { uuid: 8005, name: "双光环平A流", heroes: [5101, 5005, 5105], desc: "战歌法师攻击光环与风怒先知攻速光环互相乘算,不死斗士前排自我回血稳站,全队普攻输出被双光环持续放大。", low_heroes: [5001, 5005, 5105], }, // 8006 续航消耗流 — 双奶抬血线,克制高血 Boss 的持久战 8006: { uuid: 8006, name: "续航消耗流", heroes: [5101, 5405, 5106], desc: "不死斗士受击回血顶前排,圣言诗人治疗+生命光环抬全队血线,破甲射手以穿透增益磨掉高血 Boss,专打持久战。", }, }; /** 推荐阵容 id 列表(按品质/成型难度排序,供 UI 顺序展示) */ export const HeroComboList: number[] = [8001, 8002, 8003, 8004, 8005, 8006]; // ==================== 英雄强度评分公式 ==================== /** 英雄强度公式调参权重(可在编辑器或运行时热调) * 说明: * - 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; }