refactor(hero): 重构英雄数值系统,支持品质系数与12级职业属性加成
1. 调整英雄最大等级为99,实现近似无限升级 2. 新增防御属性加成系统,补充def_bonus相关配置与计算 3. 引入英雄品质系数机制,相邻品质基础属性相差5% 4. 新增12级职业属性专项加成:坦克加防、战士辅助加血、输出加攻 5. 更新英雄设计文档与配置示例,统一数值计算逻辑 6. 重构成长计算函数,支持防御属性成长与加成
This commit is contained in:
@@ -40,8 +40,8 @@ export enum FightSet {
|
||||
HEARTPOS = -320,//基地位置
|
||||
/** 场上英雄编制数:由开局 3 次三选一固定,玩家无法扩充 */
|
||||
HERO_FIELD_NUM = 3,
|
||||
/** 英雄可升级到的最高等级(通过升级卡提升) */
|
||||
HERO_MAX_LV = 6,
|
||||
/** 英雄可升级到的最高等级(通过升级卡提升),99 近似无限升级 */
|
||||
HERO_MAX_LV = 99,
|
||||
/** 英雄技能等级上限(无限升级下技能 5 级封顶,超出等级只长属性) */
|
||||
HERO_SKILL_MAX_LV = 5,
|
||||
/** 英雄属性随等级成长的倍率(ap/hp = base * MULTIPLIER^(lv-1)) */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { v3 } from "cc"
|
||||
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"
|
||||
@@ -107,15 +107,37 @@ export enum HGrowType {
|
||||
}
|
||||
|
||||
/** 成长类型系数表(每级增量 = 英雄基础属性 × 对应系数) */
|
||||
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 },
|
||||
export const HERO_GROW_COEF: Record<HGrowType, { hp: number; ap: number; def: number }> = {
|
||||
[HGrowType.Tank]: { hp: 1.5, ap: 0.6, def: 1.5 },
|
||||
[HGrowType.Warrior]: { hp: 1.0, ap: 1.0, def: 1.0 },
|
||||
[HGrowType.Assassin]: { hp: 0.7, ap: 1.4, def: 0.5 },
|
||||
[HGrowType.Mage]: { hp: 0.9, ap: 1.3, def: 0.5 },
|
||||
[HGrowType.Support]: { hp: 1.1, ap: 0.7, def: 1.0 },
|
||||
[HGrowType.Archer]: { hp: 0.8, ap: 1.3, def: 0.5 },
|
||||
};
|
||||
|
||||
/**
|
||||
* 英雄品质系数步长:相邻品质(card_lv)基础属性相差 5%。
|
||||
* 系数 = 1 + HERO_QUALITY_STEP × (card_lv - 1),lv1~lv5 → 1.00/1.05/1.10/1.15/1.20。
|
||||
* 仅作用于 lv1 初始基础属性(AP/HP/DEF),成长与等级 bonus 不随品质缩放。
|
||||
*/
|
||||
export const HERO_QUALITY_STEP = 0.05;
|
||||
|
||||
/** 计算英雄品质系数(相邻品质基础属性差 5%) */
|
||||
export function getHeroQualityCoef(cardLv: number): number {
|
||||
return 1 + HERO_QUALITY_STEP * (Math.max(1, cardLv) - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* lv12 职业属性专项:英雄等级达到 12 级时,按职业对单项基础属性 +50%。
|
||||
* 基数为 lv11 当前等级有效值(基础 + 成长 + lv9 bonus,不含 lv12 自身)。
|
||||
* Why: 坦克堆防、战士/辅助堆血、输出位堆攻,强化职业特色。
|
||||
*/
|
||||
export const HERO_LV12_SPECIAL_LV = 12;
|
||||
|
||||
/** lv12 专项提升的档位等级(基数取 LV12 - 1 = 11 级有效值) */
|
||||
export const HERO_LV12_BASE_LV = HERO_LV12_SPECIAL_LV - 1;
|
||||
|
||||
/**
|
||||
* 英雄位置类型(职业定位)。
|
||||
* Why: grow_type 仅驱动数值成长曲线,无法表达"这个英雄在阵容里干什么";
|
||||
@@ -139,6 +161,16 @@ export const HRoleName: Record<HRole, string> = {
|
||||
[HRole.Support]: "辅助",
|
||||
};
|
||||
|
||||
/** lv12 各职业专项属性映射(坦克堆防、战士/辅助堆血、输出位堆攻) */
|
||||
export const HERO_LV12_SPECIAL_ATTR: Record<HRole, "def" | "hp" | "ap"> = {
|
||||
[HRole.Tank]: "def",
|
||||
[HRole.Warrior]: "hp",
|
||||
[HRole.Assassin]: "ap",
|
||||
[HRole.Archer]: "ap",
|
||||
[HRole.Mage]: "ap",
|
||||
[HRole.Support]: "hp",
|
||||
};
|
||||
|
||||
/**
|
||||
* 职业基础属性模板(仅英雄使用,怪物无 role 直接手写 hp/ap/def)。
|
||||
* 英雄配置处的 hp/ap/def = 本模板值 + 该卡手动增量,模板保证同职业基准一致、增量表达个体差异。
|
||||
@@ -158,16 +190,17 @@ export const HERO_ROLE_BASE: Record<HRole, { hp: number; ap: number; def: number
|
||||
* 公式:累计 = 基础属性 × 类型系数 × (lv - 1)。
|
||||
* Why: 以英雄自身基础值为基数,自动适配低/高费卡的成长占比,避免全局固定值失衡;
|
||||
* 线性曲线在无限升级下不会指数爆炸,强度平滑可控。
|
||||
* @param hero 英雄配置(取 hp/ap 基础值与 grow_type)
|
||||
* @param hero 英雄配置(取 hp/ap/def 基础值与 grow_type)
|
||||
* @param targetLv 目标等级(≥1)
|
||||
* @returns 累计 hp/ap 增量(已取整)
|
||||
* @returns 累计 hp/ap/def 增量(已取整)
|
||||
*/
|
||||
export function calcGrowBonus(hero: Pick<heroInfo, "hp" | "ap" | "grow_type">, targetLv: number): { hp: number; ap: number } {
|
||||
export function calcGrowBonus(hero: Pick<heroInfo, "hp" | "ap" | "def" | "grow_type">, targetLv: number): { hp: number; ap: number; def: number } {
|
||||
const coef = HERO_GROW_COEF[hero.grow_type ?? HGrowType.Warrior];
|
||||
const steps = Math.max(0, Math.floor(targetLv) - 1);
|
||||
return {
|
||||
hp: Math.floor(hero.hp * coef.hp * steps),
|
||||
ap: Math.floor(hero.ap * coef.ap * steps),
|
||||
def: Math.floor(hero.def * coef.def * steps),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -295,6 +328,7 @@ export interface heroInfo {
|
||||
skills: Record<number, HSkillInfo>; // 携带技能ID列表
|
||||
ap_bonus?: LvBonusEntry[]; // 额外攻击加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档)
|
||||
hp_bonus?: LvBonusEntry[]; // 额外生命加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档)
|
||||
def_bonus?: LvBonusEntry[]; // 额外防御加成(按 lv 升序,运行时累加 ≤英雄等级 的所有档)
|
||||
info: string; // 描述文案
|
||||
/**
|
||||
* @deprecated 已废弃:无任何 UI/运行时读取。技能提升说明由 HeroSkillText 依据
|
||||
@@ -422,8 +456,10 @@ export interface LvBonusEntry {
|
||||
*=============英雄配置列表================
|
||||
* 几何王国复刻版 — 依据 英雄设计指引.md(A/B 级复刻英雄)配置
|
||||
*
|
||||
* 规则:lv3 解锁 atking/atked 触发技能,lv2 解锁 fstart,lv6/12 大招走 lv_entries 分档成长,
|
||||
* lv9 card_lv 4/5 配 field 光环,card_lv 3 配 ap_bonus/hp_bonus 基础属性+50%
|
||||
* 规则:lv1 激活 skills[0]/skills[1],lv6 解锁 atking/atked/fstart 触发技能,
|
||||
* 大招(skills[1])lv9/lv16 走 lv_entries 分档成长,lv12 按职业对单项基础属性 +50%(基数取 lv11 有效值),
|
||||
* lv9 card_lv 4/5 配 field 光环,card_lv 3 配 ap_bonus/hp_bonus 基础属性+50%,
|
||||
* 品质(card_lv)相邻基础属性差 5%(仅 lv1 初始 AP/HP/DEF)
|
||||
* 编号:本批复刻英雄集中于 5001~5009,card_lv 按配置(不遵循段位规则)
|
||||
*/
|
||||
|
||||
@@ -443,14 +479,14 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { ap: 250, bck: 30, para: 40, summon_count: 1 },
|
||||
desc: "释放能量波,对{target}造成攻击力{ap}%伤害,击退{bck},{para}%概率麻痹",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { ap: 250, bck: 60, para: 40, summon_count: 1 } },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { ap: 300, bck: 90, timed_buff_id: 7005, para: 50, summon_count: 2 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,击退{bck},{para}%概率麻痹,额外释放1次,并使目标中毒(每0.5秒受到{buff_value}点毒伤,持续{dur}秒)" },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { ap: 250, bck: 60, para: 40, summon_count: 1 } },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { ap: 300, bck: 90, timed_buff_id: 7005, para: 50, summon_count: 2 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,击退{bck},{para}%概率麻痹,额外释放1次,并使目标中毒(每0.5秒受到{buff_value}点毒伤,持续{dur}秒)" },
|
||||
],
|
||||
},
|
||||
},
|
||||
atking: {
|
||||
6010: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "雷霆万钧", t_num: 3, overrides: { para: 100 }, desc: "释放紫魔球轰击{target},{para}%概率麻痹目标" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "雷霆万钧", t_num: 3, overrides: { para: 100 }, desc: "释放紫魔球轰击{target},{para}%概率麻痹目标" },
|
||||
],
|
||||
},
|
||||
field: [
|
||||
@@ -469,14 +505,14 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { ap: 150 },
|
||||
desc: "斩出光闪,对{target}造成攻击力{ap}%伤害",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7007 }, desc: "斩出光闪,对{target}造成攻击力{ap}%伤害,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { ap: 180, hit_count: 8, num: 1 }, desc: "斩出光闪,对{target}连击{hit_count}次,每次造成攻击力{ap}%伤害,并双发{num}次" },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7007 }, desc: "斩出光闪,对{target}造成攻击力{ap}%伤害,并使目标出血(每0.5秒受到{buff_value}点伤害,持续{dur}秒)" },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { ap: 180, hit_count: 8, num: 1 }, desc: "斩出光闪,对{target}连击{hit_count}次,每次造成攻击力{ap}%伤害,并双发{num}次" },
|
||||
],
|
||||
},
|
||||
},
|
||||
atking: {
|
||||
6004: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "致命节奏", t_num: 3, overrides: { crt: 30 }, desc: "释放斩击,{crt}%概率造成暴击" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "致命节奏", t_num: 3, overrides: { crt: 30 }, desc: "释放斩击,{crt}%概率造成暴击" },
|
||||
],
|
||||
},
|
||||
field: [
|
||||
@@ -495,19 +531,19 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { ap: 150, para: 40, summon_count: 1 },
|
||||
desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,{para}%概率麻痹",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7006, para: 40, summon_count: 1 }, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,{para}%概率麻痹,并使目标攻击力{buff_value}%(持续{dur}秒)" },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { ap: 180, timed_buff_id: 7006, buff_value: -15, para: 50, summon_count: 2 } },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7006, para: 40, summon_count: 1 }, desc: "召唤落雷斩击{target},造成攻击力{ap}%伤害,{para}%概率麻痹,并使目标攻击力{buff_value}%(持续{dur}秒)" },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { ap: 180, timed_buff_id: 7006, buff_value: -15, para: 50, summon_count: 2 } },
|
||||
],
|
||||
},
|
||||
},
|
||||
atked: {
|
||||
6301: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "罗生门", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 2 }, desc: "{target}获得{ap}次格挡护盾" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "罗生门", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 2 }, desc: "{target}获得{ap}次格挡护盾" },
|
||||
],
|
||||
},
|
||||
fstart: {
|
||||
6200: [
|
||||
{ lv: 2, s_lv: SkillLv.Lv1, name: "三十六烦恼凤", t_num: 1, overrides: { ap: 500 }, desc: "入场释放剑气,对{target}造成攻击力{ap}%伤害" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "三十六烦恼凤", t_num: 1, overrides: { ap: 500 }, desc: "入场释放剑气,对{target}造成攻击力{ap}%伤害" },
|
||||
],
|
||||
},
|
||||
field: [
|
||||
@@ -526,14 +562,14 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { ap: 150, summon_count: 1 },
|
||||
desc: "释放能量波,对{target}造成攻击力{ap}%伤害",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { ap: 150, frz: 15, summon_count: 1 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,{frz}%概率冰冻" },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { ap: 180, frz: 30, hit_count: 8, summon_count: 2 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,{frz}%概率冰冻,命中{hit_count}次" },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { ap: 150, frz: 15, summon_count: 1 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,{frz}%概率冰冻" },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { ap: 180, frz: 30, hit_count: 8, summon_count: 2 }, desc: "释放能量波,对{target}造成攻击力{ap}%伤害,{frz}%概率冰冻,命中{hit_count}次" },
|
||||
],
|
||||
},
|
||||
},
|
||||
atking: {
|
||||
6009: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "霜寒之触", t_num: 3, overrides: { timed_buff_id: 7003 }, desc: "释放寒气,冰冻{target}{dur}秒" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "霜寒之触", t_num: 3, overrides: { timed_buff_id: 7003 }, desc: "释放寒气,冰冻{target}{dur}秒" },
|
||||
],
|
||||
},
|
||||
field: [
|
||||
@@ -552,19 +588,19 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { TGroup: TGroup.Self, ap: 3, summon_count: 1 },
|
||||
desc: "{target}获得{ap}次格挡护盾",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Self, ap: 5, summon_count: 1 } },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Self, ap: 6, summon_count: 2 } },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Self, ap: 5, summon_count: 1 } },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Self, ap: 6, summon_count: 2 } },
|
||||
],
|
||||
},
|
||||
},
|
||||
atked: {
|
||||
6004: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "反击减攻", t_num: 4, overrides: { timed_buff_id: 7006 }, desc: "反击使攻击者攻击力{buff_value}%,持续{dur}秒" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "反击减攻", t_num: 4, overrides: { timed_buff_id: 7006 }, desc: "反击使攻击者攻击力{buff_value}%,持续{dur}秒" },
|
||||
],
|
||||
},
|
||||
fstart: {
|
||||
6412: [
|
||||
{ lv: 2, s_lv: SkillLv.Lv1, name: "铁壁壁垒", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 50 }, desc: "{target}防御提升{ap}点" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "铁壁壁垒", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 50 }, desc: "{target}防御提升{ap}点" },
|
||||
],
|
||||
},
|
||||
dead: {
|
||||
@@ -592,19 +628,19 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { TGroup: TGroup.Team, ap: 300, summon_count: 1 },
|
||||
desc: "为{target}回复攻击力{ap}%生命",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Team, ap: 400, summon_count: 1 } },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Team, ap: 450, summon_count: 2 } },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { TGroup: TGroup.Team, ap: 400, summon_count: 1 } },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { TGroup: TGroup.Team, ap: 450, summon_count: 2 } },
|
||||
],
|
||||
},
|
||||
},
|
||||
atking: {
|
||||
6302: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "圣洁之锤", t_num: 3, overrides: { TGroup: TGroup.Self, ap: 100 }, desc: "释放圣光,为{target}回复攻击力{ap}%生命" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "圣洁之锤", t_num: 3, overrides: { TGroup: TGroup.Self, ap: 100 }, desc: "释放圣光,为{target}回复攻击力{ap}%生命" },
|
||||
],
|
||||
},
|
||||
fstart: {
|
||||
6412: [
|
||||
{ lv: 2, s_lv: SkillLv.Lv1, name: "圣光庇佑", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 30 }, desc: "{target}防御提升{ap}点" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "圣光庇佑", t_num: 1, overrides: { TGroup: TGroup.Team, ap: 30 }, desc: "{target}防御提升{ap}点" },
|
||||
],
|
||||
},
|
||||
field: [
|
||||
@@ -623,14 +659,14 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { ap: 150, summon_count: 1 },
|
||||
desc: "斩出气刃,对{target}造成攻击力{ap}%伤害",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7002, summon_count: 1 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,并使目标易伤(受到伤害加深,持续{dur}秒)" },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { ap: 180, bck: 60, timed_buff_id: 7002, buff_value: 20, summon_count: 2 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,击退{bck},并使目标易伤(持续{dur}秒)" },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { ap: 150, timed_buff_id: 7002, summon_count: 1 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,并使目标易伤(受到伤害加深,持续{dur}秒)" },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { ap: 180, bck: 60, timed_buff_id: 7002, buff_value: 20, summon_count: 2 }, desc: "斩出气刃,对{target}造成攻击力{ap}%伤害,击退{bck},并使目标易伤(持续{dur}秒)" },
|
||||
],
|
||||
},
|
||||
},
|
||||
atking: {
|
||||
6004: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "雷霆一击", t_num: 3, overrides: { bck: 40 }, desc: "重击{target},击退{bck}" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "雷霆一击", t_num: 3, overrides: { bck: 40 }, desc: "重击{target},击退{bck}" },
|
||||
],
|
||||
},
|
||||
// card_lv 3:lv9 无光环,改为基础属性+50%
|
||||
@@ -649,14 +685,14 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { ap: 300, summon_count: 1 },
|
||||
desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { ap: 300, stun: 20, summon_count: 1 }, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,{stun}%概率击晕" },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { ap: 350, stun: 35, hit_count: 8, summon_count: 2 }, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,{stun}%概率击晕,命中{hit_count}次" },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { ap: 300, stun: 20, summon_count: 1 }, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,{stun}%概率击晕" },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { ap: 350, stun: 35, hit_count: 8, summon_count: 2 }, desc: "劈出开山斧,对{target}造成攻击力{ap}%伤害,{stun}%概率击晕,命中{hit_count}次" },
|
||||
],
|
||||
},
|
||||
},
|
||||
atking: {
|
||||
6004: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "火眼金睛", t_num: 3, overrides: { crt: 25 }, desc: "释放斩击,{crt}%概率造成暴击" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "火眼金睛", t_num: 3, overrides: { crt: 25 }, desc: "释放斩击,{crt}%概率造成暴击" },
|
||||
],
|
||||
},
|
||||
field: [
|
||||
@@ -675,20 +711,20 @@ export const HeroInfo: Record<number, heroInfo> = {
|
||||
overrides: { ap: 150, summon_count: 1 },
|
||||
desc: "斩出气刃,对{target}造成攻击力{ap}%伤害",
|
||||
lv_entries: [
|
||||
{ lv: 6, s_lv: SkillLv.Lv2, overrides: { ap: 180, summon_count: 1 } },
|
||||
{ lv: 12, s_lv: SkillLv.Lv3, overrides: { ap: 200, summon_count: 2 } },
|
||||
{ lv: 9, s_lv: SkillLv.Lv2, overrides: { ap: 180, summon_count: 1 } },
|
||||
{ lv: 16, s_lv: SkillLv.Lv3, overrides: { ap: 200, summon_count: 2 } },
|
||||
],
|
||||
},
|
||||
},
|
||||
atking: {
|
||||
6302: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "嗜血战斧", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 120 }, desc: "释放嗜血斩击,为{target}回复攻击力{ap}%生命" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "嗜血战斧", t_num: 4, overrides: { TGroup: TGroup.Self, ap: 120 }, desc: "释放嗜血斩击,为{target}回复攻击力{ap}%生命" },
|
||||
],
|
||||
},
|
||||
atked: {
|
||||
// 坚硬皮肤:借 6513 防御爆发底座注入 7023 防御强化(+50%,可无限叠层)
|
||||
6513: [
|
||||
{ lv: 3, s_lv: SkillLv.Lv1, name: "坚硬皮肤", t_num: 2, overrides: { TGroup: TGroup.Self, timed_buff_id: 7023, buff_duration: 10 }, desc: "{target}防御提升{buff_value}%,持续{dur}秒" },
|
||||
{ lv: 6, s_lv: SkillLv.Lv1, name: "坚硬皮肤", t_num: 2, overrides: { TGroup: TGroup.Self, timed_buff_id: 7023, buff_duration: 10 }, desc: "{target}防御提升{buff_value}%,持续{dur}秒" },
|
||||
],
|
||||
},
|
||||
// card_lv 3:lv9 无光环,改为基础属性+50%
|
||||
@@ -964,13 +1000,14 @@ export function resolveReviveByLv(revive: LvReviveEntry[] | undefined, lv: numbe
|
||||
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 } {
|
||||
/** 计算目标等级下额外属性加成(hp/ap/def_bonus 一次性奖励 + 成长类型每级递增) */
|
||||
function getEvolveBonuses(hero: heroInfo, targetLv: number): { hp: number, ap: number, def: number } {
|
||||
const lv = Math.max(1, targetLv);
|
||||
// 成长类型线性增量(仅英雄生效,怪物无 grow_type 时走 Warrior 基准但不影响平衡,因怪物通常不填)
|
||||
const grow = hero.fac === FacSet.HERO ? calcGrowBonus(hero, lv) : { hp: 0, ap: 0 };
|
||||
const grow = hero.fac === FacSet.HERO ? calcGrowBonus(hero, lv) : { hp: 0, ap: 0, def: 0 };
|
||||
let hp = grow.hp;
|
||||
let ap = grow.ap;
|
||||
let def = grow.def;
|
||||
if (hero.hp_bonus) {
|
||||
for (const e of hero.hp_bonus) {
|
||||
if (e.lv <= lv) hp += e.value;
|
||||
@@ -981,15 +1018,57 @@ function getEvolveBonuses(hero: heroInfo, targetLv: number): { hp: number, ap: n
|
||||
if (e.lv <= lv) ap += e.value;
|
||||
}
|
||||
}
|
||||
return { hp, ap };
|
||||
if (hero.def_bonus) {
|
||||
for (const e of hero.def_bonus) {
|
||||
if (e.lv <= lv) def += e.value;
|
||||
}
|
||||
}
|
||||
return { hp, ap, def };
|
||||
}
|
||||
|
||||
/** 计算目标等级下的有效 HP/AP(固定基础值 + 成长递增与一次性加成) */
|
||||
function getEffectiveStats(hero: heroInfo, targetLv: number): { hp: number, ap: number } {
|
||||
/** 计算目标等级下的有效 HP/AP/DEF(固定基础值 + 成长递增与一次性加成) */
|
||||
export function getEffectiveStats(hero: heroInfo, targetLv: number): { hp: number, ap: number, def: number } {
|
||||
const bonuses = getEvolveBonuses(hero, targetLv);
|
||||
return {
|
||||
hp: hero.hp + bonuses.hp,
|
||||
ap: hero.ap + bonuses.ap,
|
||||
def: hero.def + bonuses.def,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算英雄展示用最终属性(含品质系数与 lv12 职业专项),供 UI 面板与运行时对齐口径。
|
||||
* 公式:基础值 × 品质系数 + 成长 + bonus,再叠加 lv12 专项(基数取 lv11 有效值)。
|
||||
* @param hero 英雄配置
|
||||
* @param targetLv 目标等级(≥1)
|
||||
* @returns 含品质与专项的最终 hp/ap/def(已取整)
|
||||
*/
|
||||
export function getHeroDisplayStats(hero: heroInfo, targetLv: number): { hp: number, ap: number, def: number } {
|
||||
const lv = Math.max(1, Math.floor(targetLv));
|
||||
const coef = getHeroQualityCoef(hero.card_lv ?? 1);
|
||||
const eff = getEffectiveStats(hero, lv);
|
||||
const stats = {
|
||||
hp: Math.round(hero.hp * coef) + (eff.hp - hero.hp),
|
||||
ap: Math.round(hero.ap * coef) + (eff.ap - hero.ap),
|
||||
def: Math.round(hero.def * coef) + (eff.def - hero.def),
|
||||
};
|
||||
// lv12 职业专项:基数为 lv11 展示有效值
|
||||
if (lv >= HERO_LV12_SPECIAL_LV && hero.role !== undefined) {
|
||||
const base11 = getHeroDisplayStatsBase(hero, HERO_LV12_BASE_LV);
|
||||
const attr = HERO_LV12_SPECIAL_ATTR[hero.role];
|
||||
stats[attr] += Math.round(base11[attr] * 0.5);
|
||||
}
|
||||
return stats;
|
||||
}
|
||||
|
||||
/** 内部:lv12 专项基数(不含 lv12 自身)的展示有效值 */
|
||||
function getHeroDisplayStatsBase(hero: heroInfo, targetLv: number): { hp: number, ap: number, def: number } {
|
||||
const coef = getHeroQualityCoef(hero.card_lv ?? 1);
|
||||
const eff = getEffectiveStats(hero, targetLv);
|
||||
return {
|
||||
hp: Math.round(hero.hp * coef) + (eff.hp - hero.hp),
|
||||
ap: Math.round(hero.ap * coef) + (eff.ap - hero.ap),
|
||||
def: Math.round(hero.def * coef) + (eff.def - hero.def),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,8 @@ revive[0]:无
|
||||
|
||||
**通用约束**:
|
||||
|
||||
- lv2 走 atking/atked/fstart 提升普攻能力;lv3/5/7 走 `skills[1].lv_entries` 提升大招;lv9 光环或属性补偿
|
||||
- 等级节奏:lv1 激活 skills[0]/skills[1];lv6 解锁 atking/atked/fstart 触发技能(1 个);大招(skills[1])lv9/lv16 走 `lv_entries` 分档提升;lv12 按职业对单项基础属性 +50%(基数取 lv11 当前等级有效值:坦克→def、战士/辅助→hp、刺客/射手/法师→ap);lv9 光环或属性补偿
|
||||
- 品质差异:相邻品质(card_lv)lv1 初始基础属性(AP/HP/DEF)相差 5%(系数 1+0.05×(card_lv-1)),其余配置参数完全一致
|
||||
- 能力只能从能力池(BuffList 7001\~7024 / FieldSkillSet 7001\~7020 / SkillSet 底座)引用 + `overrides` 数值覆盖,**禁止新增同义底座**
|
||||
|
||||
**大招召唤数约束**(`summon_count` 覆写规则):
|
||||
@@ -303,11 +304,13 @@ revive[0]:无
|
||||
## 配置检查清单
|
||||
|
||||
- [ ] `skills` 引用的 uuid 在 SkillSet 中存在,`overrides.ap` 显式写出
|
||||
- [ ] 大招(`skills[1]`)覆写 `summon_count`:lv1=1、lv3=1、lv5=2、lv7=3,通过 `lv_entries` 逐级覆写,不改动 SkillSet 底座
|
||||
- [ ] 大招(`skills[1]`)覆写 `summon_count`:lv1=1、lv9=1、lv16=2,通过 `lv_entries` 逐级覆写,不改动 SkillSet 底座
|
||||
- [ ] `timed_buff_id` 指向 BuffList 已存在条目(能力池 2.1/2.2 内)
|
||||
- [ ] debuff/buff 只通过 `overrides` 注入,未改动 SkillSet/BuffList 底座
|
||||
- [ ] `atking`/`atked`/`fstart`/`dead` 按 s\_uuid 分组、按 lv 升序
|
||||
- [ ] `atking`/`atked`/`fstart`/`dead` 按 s\_uuid 分组、按 lv 升序,触发技能统一 lv6 解锁
|
||||
- [ ] lv9:card\_lv 4/5 配 `field`;card\_lv 1/2/3 配 `ap_bonus`/`hp_bonus`(30/40/50%)
|
||||
- [ ] lv12:按职业注入单项属性 +50%(坦克 def、战士/辅助 hp、刺客/射手/法师 ap),基数取 lv11 有效值
|
||||
- [ ] 品质:card\_lv 相邻基础属性差 5%(运行时品质系数统一乘,配置保持裸值)
|
||||
- [ ] `t_num` 概率模拟符合预期(1=每次,3≈33%,4≈25%)
|
||||
- [ ] `infos` 分级说明与配置档位一一对应(面板逐条展示)
|
||||
- [ ] 近战/远程形态与 `type`/`dis` 匹配,美术资源 `path`/`icon` 就绪
|
||||
|
||||
Reference in New Issue
Block a user