diff --git a/.trae/rules/project_rules.md b/.trae/rules/project_rules.md index 451247bb..8ac21988 100644 --- a/.trae/rules/project_rules.md +++ b/.trae/rules/project_rules.md @@ -67,6 +67,7 @@ alwaysApply: true 1. **技能底座纯净化**:SkillSet 中的技能只定义基础行为(伤害、弹道、命中),**禁止**在基础配置中写死 `timed_buff_id` / `buff_type` 等效果字段 2. **效果由引用处注入**:英雄/怪物引用技能时,通过 `HSkillInfo.overrides` 按需附加 debuff/buff,实现"同一技能、不同效果" 3. **数值覆盖优先**:`ap`(伤害百分比)、`hit_count`、`crt` 等数值差异,统一由 `overrides` 覆写,而非新建相似技能 +4. **Buff 统一百分比口径**:无论永久 buff(`buff_type`)还是计时 buff(`timed_buff_id`),修饰数值均按百分比/百分点结算;`ap`/`hp_max` 按基础值相对放大,概率类属性按百分点累加 ## SkillSet 配置规范 diff --git a/assets/script/game/common/config/BuffSet.ts b/assets/script/game/common/config/BuffSet.ts index 81ebde95..3b7dbddd 100644 --- a/assets/script/game/common/config/BuffSet.ts +++ b/assets/script/game/common/config/BuffSet.ts @@ -88,8 +88,8 @@ export const BuffList: Record = { 7001: { id: 7001, name: "攻击强化", icon: "Stat_Attack_03", category: BuffCategory.Buff, duration: 10, max_stack: 0, - modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 5 }], - info: "攻击力 +5,持续 10 秒", + modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: 5 }], + info: "攻击力提升 5%,持续 10 秒", }, // 易伤(灼热火球附加;受到伤害时附加固定值,可被易伤抗性百分比减免) // 注:modifiers.attr 用 hp 仅为占位以通过 aggregateTimedMods 结构校验,实际易伤值由 HeroAtkSystem 按 VULNERABLE_BUFF_ID 直接汇总 @@ -124,8 +124,8 @@ export const BuffList: Record = { 7006: { id: 7006, name: "减攻", icon: "Stat_Attack_01", category: BuffCategory.Debuff, duration: 5, max_stack: 1, - modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: -10 }], - info: "攻击力降低 10 点,持续 5 秒", + modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: -10 }], + info: "攻击力降低 10%,持续 5 秒", }, // 出血(每层使目标被暴击率 +1%,微量伤害 DoT;暴击率加成由 HeroAtkSystem 按 BLEED_BUFF_ID 层数结算) 7007: { @@ -134,12 +134,12 @@ export const BuffList: Record = { tick: { interval: 0.5, damage_or_heal: -1, scale_by_ap_pct: 0 }, info: "微量出血,每层使自身被暴击率提升 1%,可叠加,持续 5 秒", }, - // 占卜师战前攻击强化(基础档:+30/5s;高阶通过 buff_value/buff_duration 覆写成长) + // 占卜师战前攻击强化(基础档:+30%/5s;高阶通过 buff_value/buff_duration 覆写成长) 7111: { id: 7111, name: "战前强攻", icon: "Stat_Attack_03", category: BuffCategory.Buff, duration: 5, max_stack: 0, - modifiers: [{ attr: Attrs.ap, op: ModOp.Flat, value: 30 }], - info: "攻击力 +30,持续 5 秒", + modifiers: [{ attr: Attrs.ap, op: ModOp.PercentAdd, value: 30 }], + info: "攻击力提升 30%,持续 5 秒", }, // ==================== 玩家计时性强化(药水/技能用,默认 5s) ==================== @@ -161,77 +161,77 @@ export const BuffList: Record = { 7012: { id: 7012, name: "暴击爆发", icon: "Stat_CriticalChance_02", 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 秒", }, // 击退距离强化(限时) 7013: { id: 7013, name: "击退爆发", icon: "Stat_Stun_01", category: BuffCategory.Buff, duration: 5, max_stack: 1, - modifiers: [{ attr: Attrs.knockback_chance, op: ModOp.Flat, value: 30 }], - info: "击退距离提升 30,持续 5 秒", + modifiers: [{ attr: Attrs.knockback_chance, op: ModOp.PercentAdd, value: 30 }], + info: "击退距离提升 30%,持续 5 秒", }, // 穿透强化(限时) 7014: { id: 7014, name: "穿透爆发", icon: "Stat_Tripleshot", 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 秒", }, // 攻速强化(限时,走 getEffectiveSkillCd 计时修饰) 7015: { id: 7015, name: "攻速爆发", icon: "Stat_AttackSpeed_02", 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 秒", }, // 风怒强化(限时,按概率百分点) 7016: { id: 7016, name: "风怒爆发", icon: "Stat_CriticalComboChance", 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 秒", }, // 击晕概率强化(限时) 7017: { id: 7017, name: "击晕爆发", icon: "Stat_Stun_01", 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 秒", }, // 击晕抗性强化(限时) 7018: { id: 7018, name: "击晕抗性", icon: "Stat_Armor_01", 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 秒", }, // 冰冻抗性强化(限时) 7019: { id: 7019, name: "冰冻抗性", icon: "Stat_Freeze", 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 秒", }, // 暴伤强化(限时) 7020: { id: 7020, name: "暴伤爆发", icon: "Stat_Critical_01", 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 秒", }, // 冰冻概率强化(限时) 7021: { id: 7021, name: "冰冻概率爆发", icon: "Stat_Freeze", 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 秒", }, // 穿透伤害强化(限时) 7022: { id: 7022, name: "穿透伤害爆发", icon: "Stat_Tripleshot", 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 秒", }, }; diff --git a/assets/script/game/common/config/SkillDescSet.ts b/assets/script/game/common/config/SkillDescSet.ts index 736f64f5..b399f897 100644 --- a/assets/script/game/common/config/SkillDescSet.ts +++ b/assets/script/game/common/config/SkillDescSet.ts @@ -57,16 +57,16 @@ export const SkillDescSet: Record = { verb: "", unit: "", permField: "ap", templPerm: "{target}回复攻击力{value}%生命", }, - // 6401 攻击强化:永久 ap=攻击点;计时 buff_value=攻击点 + // 6401 攻击强化:永久 ap=攻击%;计时 buff_value=攻击% 6401: { - verb: "攻击力", unit: "", permField: "ap", timedField: "buff_value", - templPerm: "{target}{verb}永久+{value}", - templTimed: "{target}{verb}+{value}, 持续{dur}秒", + verb: "攻击力", unit: "%", permField: "ap", timedField: "buff_value", + templPerm: "{target}{verb}永久+{value}{unit}", + templTimed: "{target}{verb}+{value}{unit}, 持续{dur}秒", }, - // 6402 生命强化:ap = 最大生命点 + // 6402 生命强化:ap = 最大生命% 6402: { - verb: "最大生命", unit: "", permField: "ap", - templPerm: "{target}{verb}永久+{value}", + verb: "最大生命", unit: "%", permField: "ap", + templPerm: "{target}{verb}永久+{value}{unit}", }, // 6403 暴击强化:永久 ap=暴击%;计时 buff_value=暴击% 6403: { diff --git a/assets/script/game/common/config/SkillSet.ts b/assets/script/game/common/config/SkillSet.ts index af515699..31011f48 100644 --- a/assets/script/game/common/config/SkillSet.ts +++ b/assets/script/game/common/config/SkillSet.ts @@ -357,12 +357,12 @@ export const SkillSet: Record = { 6401: { 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, - 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: { 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, - 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: { 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 = { 6411: { 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, - 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: { 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 = { }, // ==================== 计时性强化技能(药水底座,统一 5s,走 timed_buff_id) ==================== - // 注:ap 字段在此类技能中无意义,修饰数值由 BuffList 配置;hit_count=99 确保覆盖全队。 + // 注:ap 字段在此类技能中无意义,修饰数值由 BuffList 配置(PercentAdd 百分比口径);hit_count=99 确保覆盖全队。 6502: { 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, @@ -435,7 +435,7 @@ export const SkillSet: Record = { 6505: { 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, - 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: { uuid: 6506, name: "穿透爆发", sp_name: "buff_wind", icon: "Stat_Tripleshot", TGroup: TGroup.Team, readyAnm: "up_ap", endAnm: "", act: "atk", diff --git a/assets/script/game/common/config/heroSet.ts b/assets/script/game/common/config/heroSet.ts index 10258553..5035ee7b 100644 --- a/assets/script/game/common/config/heroSet.ts +++ b/assets/script/game/common/config/heroSet.ts @@ -1114,7 +1114,7 @@ function calcBuffPermanentEquivalent(buff: BuffConfig, apEff: number, cd: number } /** 计算 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 value = config.ap || 0; @@ -1131,10 +1131,12 @@ function calcSupportEffectValue(config: SkillConfig, apEff: number, cd: number, switch (config.buff_type) { 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: - return value * weights.W_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: @@ -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 { - const { ap: apEff } = getEffectiveStats(hero, targetLv); + const { hp: hpEff, ap: apEff } = getEffectiveStats(hero, targetLv); const cd = getAttackCd(hero); const config = overrides ? mergeSkillParams(skill, overrides) : skill; const weights = HERO_POWER_WEIGHTS; @@ -1168,7 +1170,7 @@ function calcSkillEffectValue(skill: SkillConfig, overrides: SkillOverrides | un // 护盾为数值减免型:1 点护盾 ≈ 1 点预期伤害减免 return (config.ap || 0) * weights.W_shield; case SkillKind.Support: - return calcSupportEffectValue(config, apEff, cd, seconds); + return calcSupportEffectValue(config, hpEff, apEff, cd, seconds); default: return 0; } diff --git a/assets/script/game/hero/HeroAttrsComp.ts b/assets/script/game/hero/HeroAttrsComp.ts index 27e712c3..702f8487 100644 --- a/assets/script/game/hero/HeroAttrsComp.ts +++ b/assets/script/game/hero/HeroAttrsComp.ts @@ -82,7 +82,7 @@ export class HeroAttrsComp extends ecs.Comp { knockback_chance: number = 0; // 击退强化(原击退概率,现转换为击退距离增量) knockback_distance: 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_dmg_bonus: number = 0; // 穿透后伤害增量(百分点,乘算加成) wfuny: number = 0; // 风怒 @@ -334,8 +334,8 @@ export class HeroAttrsComp extends ecs.Comp { /** 英雄实时暴击伤害 = 基础额外暴伤 + 驻场暴伤。 */ public getRuntimeCritDamageBonus(): number { - if (this.fac !== FacSet.HERO) return this.crit_damage; - return this.crit_damage + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroCritDamage); + if (this.fac !== FacSet.HERO) return this.critical_damage; + return this.critical_damage + HeroAttrsComp.getFieldPercentValue(FieldSkillType.HeroCritDamage); } /** 攻速加成通过缩短普通攻击技能 CD 生效,正值越高,攻击越快。 */ @@ -606,7 +606,7 @@ export class HeroAttrsComp extends ecs.Comp { this.knockback_chance = 0; this.knockback_distance = 0; this.knockback_res = 0; - this.crit_damage = 0; + this.critical_damage = 0; this.revived_count = 0; this.invincible_time = 0; this.puncture_chance = 0; diff --git a/assets/script/game/hero/SCastSystem.ts b/assets/script/game/hero/SCastSystem.ts index 3eeb6bdf..4c504beb 100644 --- a/assets/script/game/hero/SCastSystem.ts +++ b/assets/script/game/hero/SCastSystem.ts @@ -551,18 +551,24 @@ export class SCastSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate return; } - // 永久 buff 的数值直接取 config.ap(已由 SkillConfig/SkillOverrides 提供最终值) + // 永久 buff 统一按百分比结算:攻击/生命按基础值相对放大,其余按百分点累加 const totalBuffValue = config.ap; switch (config.buff_type) { - case Attrs.ap: - model.add_ap(totalBuffValue); + case Attrs.ap: { + // 攻击力按基础 ap 的百分比提升 + const addAp = Math.floor(model.ap * totalBuffValue / 100); + model.add_ap(addAp); 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; + } default: - // 除了 hp_max 和 ap,其他固定属性走统一的 add_special_attr 方法 + // 暴击/击晕/穿透/攻速等概率类属性按百分点直接累加 model.add_special_attr(config.buff_type, totalBuffValue); break; }