refactor: 统一全量buff数值为百分比口径

本次变更对齐了所有buff和技能的数值结算规则:
1.  新增项目规范明确buff数值统一使用百分比/百分点结算
2.  修改技能描述配置、属性计算逻辑,将固定数值加成改为百分比计算
3.  调整buff配置的修改类型为PercentAdd,同步更新buff说明文本
4.  重构属性计算逻辑,区分百分比加成和固定加成的处理方式
5.  更新战力计算逻辑适配新的百分比口径规则
This commit is contained in:
panFD
2026-08-16 19:21:23 +08:00
parent 284d124486
commit a5ca43a62c
7 changed files with 55 additions and 46 deletions

View File

@@ -67,6 +67,7 @@ alwaysApply: true
1. **技能底座纯净化**SkillSet 中的技能只定义基础行为(伤害、弹道、命中),**禁止**在基础配置中写死 `timed_buff_id` / `buff_type` 等效果字段 1. **技能底座纯净化**SkillSet 中的技能只定义基础行为(伤害、弹道、命中),**禁止**在基础配置中写死 `timed_buff_id` / `buff_type` 等效果字段
2. **效果由引用处注入**:英雄/怪物引用技能时,通过 `HSkillInfo.overrides` 按需附加 debuff/buff实现"同一技能、不同效果" 2. **效果由引用处注入**:英雄/怪物引用技能时,通过 `HSkillInfo.overrides` 按需附加 debuff/buff实现"同一技能、不同效果"
3. **数值覆盖优先**`ap`(伤害百分比)、`hit_count``crt` 等数值差异,统一由 `overrides` 覆写,而非新建相似技能 3. **数值覆盖优先**`ap`(伤害百分比)、`hit_count``crt` 等数值差异,统一由 `overrides` 覆写,而非新建相似技能
4. **Buff 统一百分比口径**:无论永久 buff`buff_type`)还是计时 buff`timed_buff_id`),修饰数值均按百分比/百分点结算;`ap`/`hp_max` 按基础值相对放大,概率类属性按百分点累加
## SkillSet 配置规范 ## SkillSet 配置规范

View File

@@ -88,8 +88,8 @@ export const BuffList: Record<number, BuffConfig> = {
7001: { 7001: {
id: 7001, name: "攻击强化", icon: "Stat_Attack_03", id: 7001, name: "攻击强化", icon: "Stat_Attack_03",
category: BuffCategory.Buff, duration: 10, max_stack: 0, category: BuffCategory.Buff, duration: 10, max_stack: 0,
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 5 }], modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: 5 }],
info: "攻击力 +5,持续 10 秒", info: "攻击力提升 5%,持续 10 秒",
}, },
// 易伤(灼热火球附加;受到伤害时附加固定值,可被易伤抗性百分比减免) // 易伤(灼热火球附加;受到伤害时附加固定值,可被易伤抗性百分比减免)
// 注modifiers.attr 用 hp 仅为占位以通过 aggregateTimedMods 结构校验,实际易伤值由 HeroAtkSystem 按 VULNERABLE_BUFF_ID 直接汇总 // 注modifiers.attr 用 hp 仅为占位以通过 aggregateTimedMods 结构校验,实际易伤值由 HeroAtkSystem 按 VULNERABLE_BUFF_ID 直接汇总
@@ -124,8 +124,8 @@ export const BuffList: Record<number, BuffConfig> = {
7006: { 7006: {
id: 7006, name: "减攻", icon: "Stat_Attack_01", id: 7006, name: "减攻", icon: "Stat_Attack_01",
category: BuffCategory.Debuff, duration: 5, max_stack: 1, category: BuffCategory.Debuff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: -10 }], modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: -10 }],
info: "攻击力降低 10,持续 5 秒", info: "攻击力降低 10%,持续 5 秒",
}, },
// 出血(每层使目标被暴击率 +1%,微量伤害 DoT暴击率加成由 HeroAtkSystem 按 BLEED_BUFF_ID 层数结算) // 出血(每层使目标被暴击率 +1%,微量伤害 DoT暴击率加成由 HeroAtkSystem 按 BLEED_BUFF_ID 层数结算)
7007: { 7007: {
@@ -134,12 +134,12 @@ export const BuffList: Record<number, BuffConfig> = {
tick: { interval: 0.5, damage_or_heal: -1, scale_by_ap_pct: 0 }, tick: { interval: 0.5, damage_or_heal: -1, scale_by_ap_pct: 0 },
info: "微量出血,每层使自身被暴击率提升 1%,可叠加,持续 5 秒", info: "微量出血,每层使自身被暴击率提升 1%,可叠加,持续 5 秒",
}, },
// 占卜师战前攻击强化(基础档:+30/5s高阶通过 buff_value/buff_duration 覆写成长) // 占卜师战前攻击强化(基础档:+30%/5s高阶通过 buff_value/buff_duration 覆写成长)
7111: { 7111: {
id: 7111, name: "战前强攻", icon: "Stat_Attack_03", id: 7111, name: "战前强攻", icon: "Stat_Attack_03",
category: BuffCategory.Buff, duration: 5, max_stack: 0, category: BuffCategory.Buff, duration: 5, max_stack: 0,
modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 30 }], modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: 30 }],
info: "攻击力 +30持续 5 秒", info: "攻击力提升 30%,持续 5 秒",
}, },
// ==================== 玩家计时性强化(药水/技能用,默认 5s ==================== // ==================== 玩家计时性强化(药水/技能用,默认 5s ====================
@@ -161,77 +161,77 @@ export const BuffList: Record<number, BuffConfig> = {
7012: { 7012: {
id: 7012, name: "暴击爆发", icon: "Stat_CriticalChance_02", id: 7012, name: "暴击爆发", icon: "Stat_CriticalChance_02",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.critical, op: ModOp.Flat, value: 30 }], modifiers: [{ attr: Attrs.critical, op: ModOp.PercentAdd, value: 30 }],
info: "暴击率提升 30%,持续 5 秒", info: "暴击率提升 30%,持续 5 秒",
}, },
// 击退距离强化(限时) // 击退距离强化(限时)
7013: { 7013: {
id: 7013, name: "击退爆发", icon: "Stat_Stun_01", id: 7013, name: "击退爆发", icon: "Stat_Stun_01",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.knockback_chance, op: ModOp.Flat, value: 30 }], modifiers: [{ attr: Attrs.knockback_chance, op: ModOp.PercentAdd, value: 30 }],
info: "击退距离提升 30持续 5 秒", info: "击退距离提升 30%,持续 5 秒",
}, },
// 穿透强化(限时) // 穿透强化(限时)
7014: { 7014: {
id: 7014, name: "穿透爆发", icon: "Stat_Tripleshot", id: 7014, name: "穿透爆发", icon: "Stat_Tripleshot",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.puncture_chance, op: ModOp.Flat, value: 30 }], modifiers: [{ attr: Attrs.puncture_chance, op: ModOp.PercentAdd, value: 30 }],
info: "穿透概率提升 30%,持续 5 秒", info: "穿透概率提升 30%,持续 5 秒",
}, },
// 攻速强化(限时,走 getEffectiveSkillCd 计时修饰) // 攻速强化(限时,走 getEffectiveSkillCd 计时修饰)
7015: { 7015: {
id: 7015, name: "攻速爆发", icon: "Stat_AttackSpeed_02", id: 7015, name: "攻速爆发", icon: "Stat_AttackSpeed_02",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.speed, op: ModOp.Flat, value: 40 }], modifiers: [{ attr: Attrs.speed, op: ModOp.PercentAdd, value: 40 }],
info: "攻击速度提升 40%,持续 5 秒", info: "攻击速度提升 40%,持续 5 秒",
}, },
// 风怒强化(限时,按概率百分点) // 风怒强化(限时,按概率百分点)
7016: { 7016: {
id: 7016, name: "风怒爆发", icon: "Stat_CriticalComboChance", id: 7016, name: "风怒爆发", icon: "Stat_CriticalComboChance",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.wfuny, op: ModOp.Flat, value: 20 }], modifiers: [{ attr: Attrs.wfuny, op: ModOp.PercentAdd, value: 20 }],
info: "风怒概率提升 20%,持续 5 秒", info: "风怒概率提升 20%,持续 5 秒",
}, },
// 击晕概率强化(限时) // 击晕概率强化(限时)
7017: { 7017: {
id: 7017, name: "击晕爆发", icon: "Stat_Stun_01", id: 7017, name: "击晕爆发", icon: "Stat_Stun_01",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.stun_chance, op: ModOp.Flat, value: 30 }], modifiers: [{ attr: Attrs.stun_chance, op: ModOp.PercentAdd, value: 30 }],
info: "击晕概率提升 30%,持续 5 秒", info: "击晕概率提升 30%,持续 5 秒",
}, },
// 击晕抗性强化(限时) // 击晕抗性强化(限时)
7018: { 7018: {
id: 7018, name: "击晕抗性", icon: "Stat_Armor_01", id: 7018, name: "击晕抗性", icon: "Stat_Armor_01",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.stun_res, op: ModOp.Flat, value: 50 }], modifiers: [{ attr: Attrs.stun_res, op: ModOp.PercentAdd, value: 50 }],
info: "击晕抗性提升 50%,持续 5 秒", info: "击晕抗性提升 50%,持续 5 秒",
}, },
// 冰冻抗性强化(限时) // 冰冻抗性强化(限时)
7019: { 7019: {
id: 7019, name: "冰冻抗性", icon: "Stat_Freeze", id: 7019, name: "冰冻抗性", icon: "Stat_Freeze",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.freeze_res, op: ModOp.Flat, value: 50 }], modifiers: [{ attr: Attrs.freeze_res, op: ModOp.PercentAdd, value: 50 }],
info: "冰冻抗性提升 50%,持续 5 秒", info: "冰冻抗性提升 50%,持续 5 秒",
}, },
// 暴伤强化(限时) // 暴伤强化(限时)
7020: { 7020: {
id: 7020, name: "暴伤爆发", icon: "Stat_Critical_01", id: 7020, name: "暴伤爆发", icon: "Stat_Critical_01",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.critical_damage, op: ModOp.Flat, value: 30 }], modifiers: [{ attr: Attrs.critical_damage, op: ModOp.PercentAdd, value: 30 }],
info: "暴击伤害提升 30%,持续 5 秒", info: "暴击伤害提升 30%,持续 5 秒",
}, },
// 冰冻概率强化(限时) // 冰冻概率强化(限时)
7021: { 7021: {
id: 7021, name: "冰冻概率爆发", icon: "Stat_Freeze", id: 7021, name: "冰冻概率爆发", icon: "Stat_Freeze",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.freeze_chance, op: ModOp.Flat, value: 5 }], modifiers: [{ attr: Attrs.freeze_chance, op: ModOp.PercentAdd, value: 5 }],
info: "冰冻概率提升 5%,持续 5 秒", info: "冰冻概率提升 5%,持续 5 秒",
}, },
// 穿透伤害强化(限时) // 穿透伤害强化(限时)
7022: { 7022: {
id: 7022, name: "穿透伤害爆发", icon: "Stat_Tripleshot", id: 7022, name: "穿透伤害爆发", icon: "Stat_Tripleshot",
category: BuffCategory.Buff, duration: 5, max_stack: 1, category: BuffCategory.Buff, duration: 5, max_stack: 1,
modifiers: [{ attr: Attrs.puncture_dmg_bonus, op: ModOp.Flat, value: 30 }], modifiers: [{ attr: Attrs.puncture_dmg_bonus, op: ModOp.PercentAdd, value: 30 }],
info: "穿透后伤害提升 30%,持续 5 秒", info: "穿透后伤害提升 30%,持续 5 秒",
}, },
}; };

View File

@@ -57,16 +57,16 @@ export const SkillDescSet: Record<number, SkillDescConfig> = {
verb: "", unit: "", permField: "ap", verb: "", unit: "", permField: "ap",
templPerm: "{target}回复攻击力{value}%生命", templPerm: "{target}回复攻击力{value}%生命",
}, },
// 6401 攻击强化:永久 ap=攻击;计时 buff_value=攻击 // 6401 攻击强化:永久 ap=攻击%;计时 buff_value=攻击%
6401: { 6401: {
verb: "攻击力", unit: "", permField: "ap", timedField: "buff_value", verb: "攻击力", unit: "%", permField: "ap", timedField: "buff_value",
templPerm: "{target}{verb}永久+{value}", templPerm: "{target}{verb}永久+{value}{unit}",
templTimed: "{target}{verb}+{value}, 持续{dur}秒", templTimed: "{target}{verb}+{value}{unit}, 持续{dur}秒",
}, },
// 6402 生命强化ap = 最大生命 // 6402 生命强化ap = 最大生命%
6402: { 6402: {
verb: "最大生命", unit: "", permField: "ap", verb: "最大生命", unit: "%", permField: "ap",
templPerm: "{target}{verb}永久+{value}", templPerm: "{target}{verb}永久+{value}{unit}",
}, },
// 6403 暴击强化:永久 ap=暴击%;计时 buff_value=暴击% // 6403 暴击强化:永久 ap=暴击%;计时 buff_value=暴击%
6403: { 6403: {

View File

@@ -357,12 +357,12 @@ export const SkillSet: Record<number, SkillConfig> = {
6401: { 6401: {
uuid: 6401, name: "攻击强化", sp_name: "buff_wind", icon: "Stat_Attack_03", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk", uuid: 6401, name: "攻击强化", sp_name: "buff_wind", icon: "Stat_Attack_03", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",
DTType: DTType.single, kind: SkillKind.Support, ap: 5, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, DTType: DTType.single, kind: SkillKind.Support, ap: 5, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.ap, info: "全体友方攻击力提升5, 持续1次", RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.ap, info: "全体友方攻击力提升5%, 持续1次",
}, },
6402: { 6402: {
uuid: 6402, name: "生命强化", sp_name: "buff_wind", icon: "Stat_Hp_02", TGroup: TGroup.Team, readyAnm: "up_hp", endAnm: "", act: "atk", uuid: 6402, name: "生命强化", sp_name: "buff_wind", icon: "Stat_Hp_02", TGroup: TGroup.Team, readyAnm: "up_hp", endAnm: "", act: "atk",
DTType: DTType.single, kind: SkillKind.Support, ap: 20, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, DTType: DTType.single, kind: SkillKind.Support, ap: 20, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.hp_max, info: "全体友方最大生命值提升20, 持续1次", RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.hp_max, info: "全体友方最大生命值提升20%, 持续1次",
}, },
6403: { 6403: {
uuid: 6403, name: "暴击强化", sp_name: "buff_wind", icon: "Stat_CriticalChance_02", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk", uuid: 6403, name: "暴击强化", sp_name: "buff_wind", icon: "Stat_CriticalChance_02", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",
@@ -407,7 +407,7 @@ export const SkillSet: Record<number, SkillConfig> = {
6411: { 6411: {
uuid: 6411, name: "穿透伤害强化", sp_name: "buff_wind", icon: "Stat_Tripleshot", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk", uuid: 6411, name: "穿透伤害强化", sp_name: "buff_wind", icon: "Stat_Tripleshot", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",
DTType: DTType.single, kind: SkillKind.Support, ap: 10, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, DTType: DTType.single, kind: SkillKind.Support, ap: 10, hit_count: 1, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.puncture_dmg_bonus, info: "全体友方穿透后伤害提升10%(百分点), 永久生效", RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.puncture_dmg_bonus, info: "全体友方穿透后伤害提升10%, 永久生效",
}, },
6501: { 6501: {
uuid: 6501, name: "复活", sp_name: "buff_wind", icon: "Stat_HolyDamage", TGroup: TGroup.Self, readyAnm: "up_ap", endAnm: "", act: "atk", uuid: 6501, name: "复活", sp_name: "buff_wind", icon: "Stat_HolyDamage", TGroup: TGroup.Self, readyAnm: "up_ap", endAnm: "", act: "atk",
@@ -416,7 +416,7 @@ export const SkillSet: Record<number, SkillConfig> = {
}, },
// ==================== 计时性强化技能(药水底座,统一 5s走 timed_buff_id ==================== // ==================== 计时性强化技能(药水底座,统一 5s走 timed_buff_id ====================
// 注ap 字段在此类技能中无意义,修饰数值由 BuffList 配置hit_count=99 确保覆盖全队。 // 注ap 字段在此类技能中无意义,修饰数值由 BuffList 配置PercentAdd 百分比口径)hit_count=99 确保覆盖全队。
6502: { 6502: {
uuid: 6502, name: "计时回血", sp_name: "buff_wind", icon: "Stat_PotionBoost", TGroup: TGroup.Team, readyAnm: "up_green", endAnm: "", act: "atk", uuid: 6502, name: "计时回血", sp_name: "buff_wind", icon: "Stat_PotionBoost", TGroup: TGroup.Team, readyAnm: "up_green", endAnm: "", act: "atk",
DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
@@ -435,7 +435,7 @@ export const SkillSet: Record<number, SkillConfig> = {
6505: { 6505: {
uuid: 6505, name: "击退爆发", sp_name: "buff_wind", icon: "Stat_Stun_01", TGroup: TGroup.Team, readyAnm: "up_blue", endAnm: "", act: "atk", uuid: 6505, name: "击退爆发", sp_name: "buff_wind", icon: "Stat_Stun_01", TGroup: TGroup.Team, readyAnm: "up_blue", endAnm: "", act: "atk",
DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support, DTType: DTType.single, kind: SkillKind.Support, ap: 0, hit_count: 3, hitcd: 0.2, speed: 720, with: 0, ready: 0.2, EAnm: 0, DAnm: "", IType: IType.support,
RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.knockback_chance, timed_buff_id: 7013, info: "全体友方击退距离提升30, 持续5秒", RType: RType.fixed, EType: EType.animationEnd, buff_type: Attrs.knockback_chance, timed_buff_id: 7013, info: "全体友方击退距离提升30%, 持续5秒",
}, },
6506: { 6506: {
uuid: 6506, name: "穿透爆发", sp_name: "buff_wind", icon: "Stat_Tripleshot", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk", uuid: 6506, name: "穿透爆发", sp_name: "buff_wind", icon: "Stat_Tripleshot", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk",

View File

@@ -1114,7 +1114,7 @@ function calcBuffPermanentEquivalent(buff: BuffConfig, apEff: number, cd: number
} }
/** 计算 Support 类技能单次触发的效果价值 */ /** 计算 Support 类技能单次触发的效果价值 */
function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number, seconds: number): number { function calcSupportEffectValue(config: SkillConfig, hpEff: number, apEff: number, cd: number, seconds: number): number {
const weights = HERO_POWER_WEIGHTS; const weights = HERO_POWER_WEIGHTS;
const value = config.ap || 0; const value = config.ap || 0;
@@ -1131,10 +1131,12 @@ function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number,
switch (config.buff_type) { switch (config.buff_type) {
case Attrs.ap: case Attrs.ap:
return (value / cd) * weights.W_DPS_PER_SEC * seconds; // 永久 buff 已改为百分比口径value 是百分比,需先换算为基础 ap 的绝对增量
return ((value / 100) * apEff / cd) * weights.W_DPS_PER_SEC * seconds;
case Attrs.hp_max: case Attrs.hp_max:
case Attrs.hp: case Attrs.hp:
return value * weights.W_HP; // 永久 buff 已改为百分比口径value 是百分比,需先换算为基础 hp 的绝对增量
return (value / 100) * hpEff * weights.W_HP;
case Attrs.critical: case Attrs.critical:
return (value / 100) * (apEff / cd) * 0.5 * weights.W_DPS_PER_SEC * seconds; return (value / 100) * (apEff / cd) * 0.5 * weights.W_DPS_PER_SEC * seconds;
case Attrs.critical_damage: case Attrs.critical_damage:
@@ -1154,7 +1156,7 @@ function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number,
/** 计算单条技能配置单次触发的效果价值 */ /** 计算单条技能配置单次触发的效果价值 */
function calcSkillEffectValue(skill: SkillConfig, overrides: SkillOverrides | undefined, hero: heroInfo, targetLv: number, seconds: number): number { function calcSkillEffectValue(skill: SkillConfig, overrides: SkillOverrides | undefined, hero: heroInfo, targetLv: number, seconds: number): number {
const { ap: apEff } = getEffectiveStats(hero, targetLv); const { hp: hpEff, ap: apEff } = getEffectiveStats(hero, targetLv);
const cd = getAttackCd(hero); const cd = getAttackCd(hero);
const config = overrides ? mergeSkillParams(skill, overrides) : skill; const config = overrides ? mergeSkillParams(skill, overrides) : skill;
const weights = HERO_POWER_WEIGHTS; const weights = HERO_POWER_WEIGHTS;
@@ -1168,7 +1170,7 @@ function calcSkillEffectValue(skill: SkillConfig, overrides: SkillOverrides | un
// 护盾为数值减免型1 点护盾 ≈ 1 点预期伤害减免 // 护盾为数值减免型1 点护盾 ≈ 1 点预期伤害减免
return (config.ap || 0) * weights.W_shield; return (config.ap || 0) * weights.W_shield;
case SkillKind.Support: case SkillKind.Support:
return calcSupportEffectValue(config, apEff, cd, seconds); return calcSupportEffectValue(config, hpEff, apEff, cd, seconds);
default: default:
return 0; return 0;
} }

View File

@@ -82,7 +82,7 @@ export class HeroAttrsComp extends ecs.Comp {
knockback_chance: number = 0; // 击退强化(原击退概率,现转换为击退距离增量) knockback_chance: number = 0; // 击退强化(原击退概率,现转换为击退距离增量)
knockback_distance: number = 0; // 击退距离强化 knockback_distance: number = 0; // 击退距离强化
knockback_res: number = 0; // 击退抗性(削减击退距离增量) knockback_res: number = 0; // 击退抗性(削减击退距离增量)
crit_damage: number = 0; // 额外暴击伤害 critical_damage: number = 0; // 额外暴击伤害(与 Attrs.critical_damage 同名,供 add_special_attr 动态累加)
puncture_chance: number = 0; // 穿透概率 puncture_chance: number = 0; // 穿透概率
puncture_dmg_bonus: number = 0; // 穿透后伤害增量(百分点,乘算加成) puncture_dmg_bonus: number = 0; // 穿透后伤害增量(百分点,乘算加成)
wfuny: number = 0; // 风怒 wfuny: number = 0; // 风怒
@@ -334,8 +334,8 @@ export class HeroAttrsComp extends ecs.Comp {
/** 英雄实时暴击伤害 = 基础额外暴伤 + 驻场暴伤。 */ /** 英雄实时暴击伤害 = 基础额外暴伤 + 驻场暴伤。 */
public getRuntimeCritDamageBonus(): number { public getRuntimeCritDamageBonus(): number {
if (this.fac !== FacSet.HERO) return this.crit_damage; if (this.fac !== FacSet.HERO) return this.critical_damage;
return this.crit_damage + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroCritDamage); return this.critical_damage + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroCritDamage);
} }
/** 攻速加成通过缩短普通攻击技能 CD 生效,正值越高,攻击越快。 */ /** 攻速加成通过缩短普通攻击技能 CD 生效,正值越高,攻击越快。 */
@@ -606,7 +606,7 @@ export class HeroAttrsComp extends ecs.Comp {
this.knockback_chance = 0; this.knockback_chance = 0;
this.knockback_distance = 0; this.knockback_distance = 0;
this.knockback_res = 0; this.knockback_res = 0;
this.crit_damage = 0; this.critical_damage = 0;
this.revived_count = 0; this.revived_count = 0;
this.invincible_time = 0; this.invincible_time = 0;
this.puncture_chance = 0; this.puncture_chance = 0;

View File

@@ -551,18 +551,24 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate
return; return;
} }
// 永久 buff 的数值直接取 config.ap已由 SkillConfig/SkillOverrides 提供最终值) // 永久 buff 统一按百分比结算:攻击/生命按基础值相对放大,其余按百分点累加
const totalBuffValue = config.ap; const totalBuffValue = config.ap;
switch (config.buff_type) { switch (config.buff_type) {
case Attrs.ap: case Attrs.ap: {
model.add_ap(totalBuffValue); // 攻击力按基础 ap 的百分比提升
const addAp = Math.floor(model.ap * totalBuffValue / 100);
model.add_ap(addAp);
break; break;
case Attrs.hp_max: }
model.add_hp_max(totalBuffValue); case Attrs.hp_max: {
// 最大生命按基础 hp_max 的百分比提升
const addHp = Math.floor(model.hp_max * totalBuffValue / 100);
model.add_hp_max(addHp);
break; break;
}
default: default:
// 除了 hp_max 和 ap其他固定属性走统一的 add_special_attr 方法 // 暴击/击晕/穿透/攻速等概率类属性按百分点直接累加
model.add_special_attr(config.buff_type, totalBuffValue); model.add_special_attr(config.buff_type, totalBuffValue);
break; break;
} }